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();
int numfaces = (!subdivision) ? b_mesh.loop_triangles.length() : b_mesh.polygons.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);
/* 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.
* Also in edit mode do we need to make a copy, to ensure data layers like
* UV are not empty. */
if (mesh.is_editmode() ||
(mesh.use_auto_smooth() && subdivision_type == Mesh::SUBDIVISION_NONE)) {
if (mesh.is_editmode() || (mesh.normal_domain_all_info()== BL::Mesh::normal_domain_all_info_POINT &&
subdivision_type == Mesh::SUBDIVISION_NONE)) {
BL::Depsgraph depsgraph(PointerRNA_NULL);
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
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.split_faces(false);
}

View File

@ -186,28 +186,6 @@ class DATA_PT_context_mesh(MeshButtonsPanel, Panel):
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):
bl_label = "Texture Space"
bl_options = {'DEFAULT_CLOSED'}
@ -738,7 +716,6 @@ classes = (
DATA_PT_vertex_colors,
DATA_PT_face_maps,
DATA_PT_mesh_attributes,
DATA_PT_normals,
DATA_PT_texture_space,
DATA_PT_remesh,
DATA_PT_customdata,

View File

@ -118,7 +118,7 @@ const float (*BKE_editmesh_vert_coords_when_deformed(struct Depsgraph *depsgraph
int *r_vert_len,
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);
#ifdef __cplusplus

View File

@ -364,11 +364,6 @@ void BKE_mesh_calc_poly_normal(const int *poly_verts,
int verts_num,
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.
*/
@ -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);
/* In DerivedMesh.cc */
void BKE_mesh_wrapper_deferred_finalize_mdata(struct Mesh *me_eval,
const struct CustomData_MeshMasks *cd_mask_finalize);
void BKE_mesh_wrapper_deferred_finalize_mdata(struct Mesh *me_eval);
/* **** Depsgraph evaluation **** */

View File

@ -98,7 +98,7 @@ void normals_calc_loop(Span<float3> vert_positions,
Span<float3> poly_normals,
const VArray<bool> &sharp_edges,
const VArray<bool> &sharp_faces,
short (*clnors_data)[2],
const short2 *custom_normals_data,
MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals);
@ -112,7 +112,7 @@ void normals_loop_custom_set(Span<float3> vert_positions,
const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges,
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,
Span<MEdge> edges,
@ -124,7 +124,7 @@ void normals_loop_custom_set_from_verts(Span<float3> vert_positions,
const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges,
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.

View File

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

View File

@ -83,10 +83,8 @@ using blender::VArray;
#endif
static void mesh_init_origspace(Mesh *mesh);
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, const CustomData_MeshMasks *final_datamask);
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final);
static void editbmesh_calc_modifier_final_normals_or_defer(Mesh *mesh_final);
/* -------------------------------------------------------------------- */
@ -440,21 +438,17 @@ static void add_orco_mesh(
}
}
static void mesh_calc_modifier_final_normals(const Mesh *mesh_input,
const CustomData_MeshMasks *final_datamask,
const bool sculpt_dyntopo,
Mesh *mesh_final)
static void mesh_calc_modifier_final_normals(const bool sculpt_dyntopo, Mesh *mesh_final)
{
/* Compute normals. */
const bool calc_loop_normals = mesh_final->normal_domain_all_info() == ATTR_DOMAIN_CORNER;
const eAttrDomain domain = mesh_final->normal_domain_all_info();
/* Needed as `final_datamask` is not preserved outside modifier stack evaluation. */
SubsurfRuntimeData *subsurf_runtime_data = mesh_final->runtime->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
* of deferred CPU subdivision, this will be computed when the wrapper is generated. */
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,
* note that this isn't a problem for subsurf (only quads) or edit-mode
* 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();
HooglyBoogly marked this conversation as resolved Outdated

missing word after the

missing word after `the`
}
}
}
}
HooglyBoogly marked this conversation as resolved Outdated

Shouldn't this be ATTR_DOMAIN_VERT ?

Shouldn't this be `ATTR_DOMAIN_VERT` ?
@ -487,11 +486,10 @@ static void mesh_calc_finalize(const Mesh *mesh_input, Mesh *mesh_eval)
mesh_eval->edit_mesh = mesh_input->edit_mesh;
}
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval,
const CustomData_MeshMasks *cd_mask_finalize)
void BKE_mesh_wrapper_deferred_finalize_mdata(Mesh *me_eval)
{
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 & ~(1 << ME_WRAPPER_TYPE_BMESH));
}
@ -970,7 +968,7 @@ static void mesh_calc_modifiers(struct Depsgraph *depsgraph,
/* Compute normals. */
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);
}
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. */
blender::threading::isolate_task([&] {
mesh_final = BKE_mesh_copy_for_eval(mesh_input, true);
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);
runtime->mesh_eval = mesh_final;
});
@ -1047,17 +1044,16 @@ bool editbmesh_modifier_is_enabled(const Scene *scene,
return true;
}
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
const CustomData_MeshMasks *final_datamask)
static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final)
{
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;
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
* wrapper is generated. */
if (!subsurf_runtime_data || subsurf_runtime_data->resolution == 0) {
@ -1065,14 +1061,32 @@ static void editbmesh_calc_modifier_final_normals(Mesh *mesh_final,
}
}
else {
/* Same as #mesh_calc_modifiers.
* If using loop normals, poly normals have already been computed. */
BKE_mesh_ensure_normals_for_display(mesh_final);
switch (mesh_final->runtime->wrapper_type) {
case ME_WRAPPER_TYPE_SUBD:
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(
Mesh *mesh_final, const CustomData_MeshMasks *final_datamask)
static void editbmesh_calc_modifier_final_normals_or_defer(Mesh *mesh_final)
{
if (mesh_final->runtime->wrapper_type != ME_WRAPPER_TYPE_MDATA) {
/* Generated at draw time. */
@ -1081,7 +1095,7 @@ static void editbmesh_calc_modifier_final_normals_or_defer(
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,
@ -1362,9 +1376,9 @@ static void editbmesh_calc_modifiers(struct Depsgraph *depsgraph,
}
/* 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)) {
editbmesh_calc_modifier_final_normals_or_defer(mesh_cage, &final_datamask);
editbmesh_calc_modifier_final_normals_or_defer(mesh_cage);
}
/* 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 *>(
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));
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));
}
@ -1503,7 +1503,6 @@ bool BKE_object_data_transfer_ex(struct Depsgraph *depsgraph,
if (DT_DATATYPE_IS_LOOP(dtdata_type)) {
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::OffsetIndices polys_dst = me_dst->polys();
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,
positions_dst,
num_verts_dst,
edges_dst.data(),
edges_dst.size(),
corner_verts_dst.data(),
corner_verts_dst.size(),
polys_dst,

View File

@ -758,7 +758,6 @@ static GeometrySet curve_calc_modifiers_post(Depsgraph *depsgraph,
if (geometry_set.has_mesh()) {
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));
*((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);
}
void BKE_editmesh_lnorspace_update(BMEditMesh *em, Mesh *me)
void BKE_editmesh_lnorspace_update(BMEditMesh *em)
{
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);
const blender::VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
"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));
blender::bke::mesh::normals_calc_loop(
{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) {
blender::Array<blender::float3> loop_normals(result_corner_verts.size());
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));
MLoopNorSpaceArray lnors_spacearr = {nullptr};

View File

@ -319,8 +319,8 @@ enum class BoolArrayMix {
AllTrue,
Mixed,
};
BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray,
const blender::IndexRange range_to_check)
static BoolArrayMix bool_array_mix_calc(const VArray<bool> &varray,
const blender::IndexRange range_to_check)
{
using namespace blender;
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 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());
}
@ -381,9 +381,11 @@ eAttrDomain Mesh::normal_domain_all_info() const
{
using namespace blender;
using namespace blender::bke;
const short(*custom_normals)[2] = static_cast<const short(*)[2]>(
CustomData_get_layer(&this->ldata, CD_CUSTOMLOOPNORMAL));
if (custom_normals) {
if (this->totpoly == 0) {
return ATTR_DOMAIN_POINT;
}
if (CustomData_has_layer(&this->ldata, CD_CUSTOMLOOPNORMAL)) {
return ATTR_DOMAIN_CORNER;
}
@ -520,7 +522,7 @@ blender::Span<blender::float3> Mesh::corner_normals() const
"sharp_edge", ATTR_DOMAIN_EDGE, false);
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
"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));
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());
}
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,
const int numLoops,
const char data_type)
@ -1589,7 +1571,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
const Span<float3> poly_normals,
const VArray<bool> &sharp_edges,
const VArray<bool> &sharp_faces,
short (*clnors_data)[2],
const short2 *custom_normals_data,
MLoopNorSpaceArray *r_lnors_spacearr,
MutableSpan<float3> r_loop_normals)
{
@ -1626,7 +1608,7 @@ void normals_calc_loop(const Span<float3> vert_positions,
SCOPED_TIMER_AVERAGED(__func__);
#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! */
r_lnors_spacearr = &_lnors_spacearr;
}
@ -1638,8 +1620,8 @@ void normals_calc_loop(const Span<float3> vert_positions,
LoopSplitTaskDataCommon common_data;
common_data.lnors_spacearr = r_lnors_spacearr;
common_data.loop_normals = r_loop_normals;
common_data.clnors_data = {reinterpret_cast<short2 *>(clnors_data),
clnors_data ? corner_verts.size() : 0};
common_data.clnors_data = {const_cast<short2 *>(custom_normals_data),
custom_normals_data ? corner_verts.size() : 0};
common_data.positions = vert_positions;
common_data.edges = edges;
common_data.polys = polys;
@ -1704,7 +1686,7 @@ static void mesh_normals_loop_custom_set(Span<float3> positions,
const bool use_vertices,
MutableSpan<float3> r_custom_loop_normals,
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
* 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,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_loop_normals,
short (*r_clnors_data)[2])
short2 *r_clnors_data)
{
mesh_normals_loop_custom_set(vert_positions,
edges,
@ -1952,7 +1934,7 @@ void normals_loop_custom_set_from_verts(const Span<float3> vert_positions,
const VArray<bool> &sharp_faces,
MutableSpan<bool> sharp_edges,
MutableSpan<float3> r_custom_vert_normals,
short (*r_clnors_data)[2])
short2 *r_clnors_data)
{
mesh_normals_loop_custom_set(vert_positions,
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)
{
short(*clnors)[2];
short2 *clnors;
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);
if (clnors != nullptr) {
memset(clnors, 0, sizeof(*clnors) * size_t(numloops));
}
else {
clnors = (short(*)[2])CustomData_add_layer(
clnors = (short2 *)CustomData_add_layer(
&mesh->ldata, CD_CUSTOMLOOPNORMAL, CD_SET_DEFAULT, numloops);
}
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 float (*vert_positions_dst)[3],
const int numverts_dst,
const MEdge *edges_dst,
const int numedges_dst,
const int *corner_verts_dst,
const int numloops_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->poly_normals_dirty = true;
mesh->runtime->corner_normals_dirty = true;
}
void BKE_mesh_tag_positions_changed(Mesh *mesh)
{
mesh->runtime->vert_normals_dirty = true;
mesh->runtime->poly_normals_dirty = true;
mesh->runtime->corner_normals_dirty = true;
free_bvh_cache(*mesh->runtime);
mesh->runtime->looptris_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) {
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
@ -338,8 +338,9 @@ static Mesh *mesh_wrapper_ensure_subdivision(Mesh *me)
Mesh *subdiv_mesh = BKE_subdiv_to_mesh(subdiv, &mesh_settings, me);
if (use_clnors) {
BKE_mesh_set_custom_normals(
subdiv_mesh, reinterpret_cast<const float(*)[3]>(subdiv_mesh->corner_normals().data()));
BKE_mesh_set_custom_normals(subdiv_mesh,
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)) {

View File

@ -11,6 +11,8 @@
* To update preference defaults see `userdef_default.c`.
*/
#define DNA_DEPRECATED_ALLOW
#include "MEM_guardedalloc.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},
bmo_enum_bevel_miter_type}, /* outer miter kind */
{"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 */
{"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. */

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_inner = BMO_slot_int_get(op->slots_in, "miter_inner");
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 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_inner,
spread,
smoothresh,
custom_profile,
vmesh_method);

View File

@ -367,8 +367,6 @@ typedef struct BevelParams {
int vmesh_method;
/** Amount to spread when doing inside miter. */
float spread;
/** Mesh's smoothresh, used if hardening. */
float smoothresh;
} BevelParams;
// #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
* be smooth. */
if (cd_clnors_offset == -1) {
BM_edges_sharp_from_angle_set(bm, bp->smoothresh);
bevel_edges_sharp_boundary(bm, bp);
}
@ -7724,7 +7721,6 @@ void BM_mesh_bevel(BMesh *bm,
const int miter_outer,
const int miter_inner,
const float spread,
const float smoothresh,
const struct CurveProfile *custom_profile,
const int vmesh_method)
{
@ -7757,7 +7753,6 @@ void BM_mesh_bevel(BMesh *bm,
.miter_outer = miter_outer,
.miter_inner = miter_inner,
.spread = spread,
.smoothresh = smoothresh,
.face_hash = NULL,
.profile_type = profile_type,
.custom_profile = custom_profile,

View File

@ -41,6 +41,5 @@ void BM_mesh_bevel(BMesh *bm,
int miter_outer,
int miter_inner,
float spread,
float smoothresh,
const struct CurveProfile *custom_profile,
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);
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);
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 "
"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 "
"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",
BM_ELEM_SELECT,
offset,
@ -360,7 +360,6 @@ static bool edbm_bevel_calc(wmOperator *op)
miter_outer,
miter_inner,
spread,
me->smoothresh,
opdata->custom_profile,
vmesh_method);

View File

@ -8392,7 +8392,7 @@ static bool point_normals_init(bContext *C, wmOperator *op)
BMEditMesh *em = BKE_editmesh_from_object(obedit);
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);
op->customdata = lnors_ed_arr;
@ -9018,7 +9018,7 @@ static int normals_split_merge(bContext *C, const bool do_merge)
BMEdge *e;
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
* 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;
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data));
BKE_editmesh_lnorspace_update(em);
if (do_merge) {
normals_merge(bm, lnors_ed_arr);
@ -9157,7 +9157,7 @@ static int edbm_average_normals_exec(bContext *C, wmOperator *op)
BMIter fiter;
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);
@ -9404,7 +9404,7 @@ static int edbm_normals_tools_exec(bContext *C, wmOperator *op)
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);
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");
BKE_editmesh_lnorspace_update(em, static_cast<Mesh *>(obedit->data));
BKE_editmesh_lnorspace_update(em);
float(*vert_normals)[3] = static_cast<float(*)[3]>(
MEM_mallocN(sizeof(*vert_normals) * bm->totvert, __func__));
@ -9735,7 +9735,7 @@ static int edbm_smooth_normals_exec(bContext *C, wmOperator *op)
BMLoop *l;
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);
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];
}
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)
{
using namespace blender;
@ -1450,7 +1455,6 @@ void ED_mesh_split_faces(Mesh *mesh)
{
using namespace blender;
const OffsetIndices polys = mesh->polys();
const Span<int> corner_verts = mesh->corner_verts();
const Span<int> corner_edges = mesh->corner_edges();
const bke::AttributeAccessor attributes = mesh->attributes();
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) {
const bool preserve_clnor = RNA_property_boolean_get(op->ptr, prop);
if (preserve_clnor) {
BKE_editmesh_lnorspace_update(em, tc->obedit->data);
BKE_editmesh_lnorspace_update(em);
t->flag |= T_CLNOR_REBUILD;
}
BM_lnorspace_invalidate(em->bm, true);

View File

@ -128,7 +128,7 @@ void initNormalRotation(TransInfo *t)
BMEditMesh *em = BKE_editmesh_from_object(tc->obedit);
BMesh *bm = em->bm;
BKE_editmesh_lnorspace_update(em, tc->obedit->data);
BKE_editmesh_lnorspace_update(em);
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,
std::vector<int32_t> &indices,
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)
: 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<int32_t> poly_verts, loop_counts;
std::vector<int32_t> edge_crease_indices, edge_crease_lengths, vert_crease_indices;
bool has_flat_poly = false;
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_vert_creases(mesh, vert_crease_indices, vert_crease_sharpness);

View File

@ -16,7 +16,6 @@
#define _DNA_DEFAULT_Mesh \
{ \
.texspace_size = {1.0f, 1.0f, 1.0f}, \
.smoothresh = DEG2RADF(30), \
.texspace_flag = ME_TEXSPACE_FLAG_AUTO, \
.remesh_voxel_size = 0.1f, \
.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.
*/
float smoothresh;
float smoothresh DNA_DEPRECATED;
/** Per-mesh settings for voxel remesh. */
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_domain_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_color_attribute_domain_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},
};
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[] = {
{ATTR_DOMAIN_POINT, "POINT", 0, "Point", "Attribute on point"},
{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);
const int index = rna_MeshLoop_index_get(ptr);
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) {
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]);
}
else {
@ -2043,6 +2043,12 @@ int rna_Mesh_loops_lookup_int(PointerRNA *ptr, int index, PointerRNA *r_ptr)
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)
{
const Mesh *mesh = rna_mesh(ptr);
@ -4217,6 +4223,12 @@ static void rna_def_mesh(BlenderRNA *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);
RNA_def_property_struct_type(prop, "MeshNormalValue");
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);
}
static void rna_Mesh_free_normals_split(Mesh *mesh)
static void rna_Mesh_free_normals_split(Mesh *UNUSED(mesh))
{
/* 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,
value,
offset_type,
@ -214,7 +212,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
miter_outer,
miter_inner,
spread,
mesh->smoothresh,
bmd->custom_profile,
bmd->vmesh_method);

View File

@ -222,7 +222,7 @@ static void normalEditModifier_do_radial(NormalEditModifierData *enmd,
const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh,
short (*clnors)[2],
blender::short2 *clnors,
blender::MutableSpan<blender::float3> loop_normals,
const short mix_mode,
const float mix_factor,
@ -353,7 +353,7 @@ static void normalEditModifier_do_directional(NormalEditModifierData *enmd,
const ModifierEvalContext * /*ctx*/,
Object *ob,
Mesh *mesh,
short (*clnors)[2],
blender::short2 *clnors,
blender::MutableSpan<blender::float3> loop_normals,
const short mix_mode,
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>(
"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()));
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()));
loop_normals.reinitialize(corner_verts.size());
const VArray<bool> sharp_faces = attributes.lookup_or_default<bool>(
@ -543,7 +543,7 @@ static Mesh *normalEditModifier_do(NormalEditModifierData *enmd,
}
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()));
}

View File

@ -78,7 +78,7 @@ struct WeightedNormalData {
blender::Span<int> corner_verts;
blender::Span<int> corner_edges;
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. */
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_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<blender::float3> poly_normals = wn_data->poly_normals;
@ -513,7 +513,6 @@ static Mesh *modifyMesh(ModifierData *md, const ModifierEvalContext *ctx, Mesh *
{
using namespace blender;
WeightedNormalModifierData *wnmd = (WeightedNormalModifierData *)md;
Object *ob = ctx->object;
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;
}
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));
/* Keep info whether we had clnors,
* it helps when generating clnor spaces and default normals. */
const bool has_clnors = clnors != nullptr;
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()));
}