Mesh: Tag normals dirty instead of calculating
Because mesh vertex and face normals are just derived data, they can be calculated lazily instead of eagerly. Often normal calculation is a relatively expensive task, and the calculation is often redundant if the mesh is deformed afterwards anyway. Instead, normals should be calculated only when they are needed. This commit moves in that direction by adding a new function to tag a mesh's normals dirty and replacing normal calculation with it in some places. Differential Revision: https://developer.blender.org/D12107
This commit is contained in:
parent
a2203a27d9
commit
8b93265c19
|
@ -280,6 +280,7 @@ void BKE_mesh_recalc_looptri_with_normals(const struct MLoop *mloop,
|
|||
|
||||
/* *** mesh_normals.cc *** */
|
||||
|
||||
void BKE_mesh_normals_tag_dirty(struct Mesh *mesh);
|
||||
void BKE_mesh_calc_normals_mapping_simple(struct Mesh *me);
|
||||
void BKE_mesh_calc_normals_mapping(struct MVert *mverts,
|
||||
int numVerts,
|
||||
|
|
|
@ -63,6 +63,12 @@ static CLG_LogRef LOG = {"bke.mesh_normals"};
|
|||
/** \name Mesh Normal Calculation
|
||||
* \{ */
|
||||
|
||||
void BKE_mesh_normals_tag_dirty(Mesh *mesh)
|
||||
{
|
||||
mesh->runtime.cd_dirty_vert |= CD_MASK_NORMAL;
|
||||
mesh->runtime.cd_dirty_poly |= CD_MASK_NORMAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* Call when there are no polygons.
|
||||
*/
|
||||
|
|
|
@ -270,7 +270,7 @@ static Mesh *remesh_voxel_volume_to_mesh(const openvdb::FloatGrid::Ptr level_set
|
|||
}
|
||||
|
||||
BKE_mesh_calc_edges(mesh, false, false);
|
||||
BKE_mesh_calc_normals(mesh);
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
|
|
@ -159,7 +159,7 @@ static Mesh *new_mesh_from_openvdb_data(Span<openvdb::Vec3s> verts,
|
|||
}
|
||||
|
||||
BKE_mesh_calc_edges(mesh, false, false);
|
||||
BKE_mesh_calc_normals(mesh);
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -166,9 +166,10 @@ static int voxel_remesh_exec(bContext *C, wmOperator *op)
|
|||
Mesh *mesh_fixed_poles = BKE_mesh_remesh_voxel_fix_poles(new_mesh);
|
||||
BKE_id_free(nullptr, new_mesh);
|
||||
new_mesh = mesh_fixed_poles;
|
||||
BKE_mesh_calc_normals(new_mesh);
|
||||
}
|
||||
|
||||
BKE_mesh_calc_normals(new_mesh);
|
||||
|
||||
if (mesh->flag & ME_REMESH_REPROJECT_VOLUME || mesh->flag & ME_REMESH_REPROJECT_PAINT_MASK ||
|
||||
mesh->flag & ME_REMESH_REPROJECT_SCULPT_FACE_SETS) {
|
||||
BKE_mesh_runtime_clear_geometry(mesh);
|
||||
|
|
|
@ -150,7 +150,7 @@ static Mesh *hull_from_bullet(const Mesh *mesh, Span<float3> coords)
|
|||
|
||||
plConvexHullDelete(hull);
|
||||
|
||||
BKE_mesh_calc_normals(result);
|
||||
BKE_mesh_normals_tag_dirty(result);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
@ -299,7 +299,7 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
|
|||
mesh->medge[0].v1 = 0;
|
||||
mesh->medge[0].v2 = 1;
|
||||
mesh->medge[0].flag |= ME_LOOSEEDGE;
|
||||
BKE_mesh_calc_normals(mesh);
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
@ -534,12 +534,10 @@ Mesh *create_cylinder_or_cone_mesh(const float radius_top,
|
|||
}
|
||||
}
|
||||
|
||||
BKE_mesh_calc_normals(mesh);
|
||||
BKE_mesh_normals_tag_dirty(mesh);
|
||||
|
||||
calculate_uvs(mesh, top_is_point, bottom_is_point, verts_num, fill_type);
|
||||
|
||||
BLI_assert(BKE_mesh_is_valid(mesh));
|
||||
|
||||
return mesh;
|
||||
}
|
||||
|
||||
|
|
|
@ -88,7 +88,7 @@ static void geo_node_mesh_subdivide_exec(GeoNodeExecParams params)
|
|||
}
|
||||
|
||||
Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
|
||||
BKE_mesh_calc_normals(mesh_out);
|
||||
BKE_mesh_normals_tag_dirty(mesh_out);
|
||||
|
||||
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
||||
mesh_component.replace(mesh_out);
|
||||
|
|
|
@ -93,7 +93,7 @@ static void geo_node_subdivision_surface_exec(GeoNodeExecParams params)
|
|||
}
|
||||
|
||||
Mesh *mesh_out = BKE_subdiv_to_mesh(subdiv, &mesh_settings, mesh_in);
|
||||
BKE_mesh_calc_normals(mesh_out);
|
||||
BKE_mesh_normals_tag_dirty(mesh_out);
|
||||
|
||||
MeshComponent &mesh_component = geometry_set.get_component_for_write<MeshComponent>();
|
||||
mesh_component.replace(mesh_out);
|
||||
|
|
Loading…
Reference in New Issue