[Bf-blender-cvs] [d1e401220b3] temp-vert-normals-cleanup: Cleanups to subdiv code removing normal calculation

Hans Goudey noreply at git.blender.org
Wed Jan 5 18:11:27 CET 2022


Commit: d1e401220b3fab153508078a6abcadcada42c8a0
Author: Hans Goudey
Date:   Wed Jan 5 11:05:40 2022 -0600
Branches: temp-vert-normals-cleanup
https://developer.blender.org/rBd1e401220b3fab153508078a6abcadcada42c8a0

Cleanups to subdiv code removing normal calculation

===================================================================

M	source/blender/blenkernel/intern/subdiv_mesh.c

===================================================================

diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 2e857608369..a06367990c9 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -59,21 +59,8 @@ typedef struct SubdivMeshContext {
   /* UV layers interpolation. */
   int num_uv_layers;
   MLoopUV *uv_layers[MAX_MTFACE];
-  /* Accumulated values.
-   *
-   * Averaging is happening for vertices along the coarse edges and corners.
-   * This is needed for both displacement and normals.
-   *
-   * Displacement is being accumulated to a vertices coordinates, since those
-   * are not needed during traversal of edge/corner vertices.
-   *
-   * This normal array is owned by #subdiv_mesh. */
-  float (*accumulated_normals)[3];
   /* Per-subdivided vertex counter of averaged values. */
   int *accumulated_counters;
-  /* Denotes whether normals can be evaluated from a limit surface. One case
-   * when it's not possible is when displacement is used. */
-  bool can_evaluate_normals;
   bool have_displacement;
 } SubdivMeshContext;
 
@@ -101,16 +88,6 @@ static void subdiv_mesh_ctx_cache_custom_data_layers(SubdivMeshContext *ctx)
 
 static void subdiv_mesh_prepare_accumulator(SubdivMeshContext *ctx, int num_vertices)
 {
-  /* Even though #can_evaluated_normals is false, a buffer for the normals is necessary,
-   * since previously the code was evaluating into #Mert.no directly. */
-  ctx->accumulated_normals = BKE_mesh_vertex_normals_for_write(ctx->subdiv_mesh);
-  BKE_mesh_vertex_normals_clear_dirty(ctx->subdiv_mesh);
-  /* TODO(sergey): Technically, this is overallocating, we don't need memory
-   * for an inner subdivision vertices. */
-  memset(ctx->accumulated_normals, 0, sizeof(float[3]) * num_vertices);
-  if (!ctx->can_evaluate_normals && !ctx->have_displacement) {
-    return;
-  }
   ctx->accumulated_counters = MEM_calloc_arrayN(
       num_vertices, sizeof(*ctx->accumulated_counters), "subdiv accumulated counters");
 }
@@ -451,48 +428,23 @@ static void subdiv_mesh_tls_free(void *tls_v)
 
 /** \} */
 
-/* -------------------------------------------------------------------- */
-/** \name Evaluation helper functions
- * \{ */
-
-static void eval_final_point_and_vertex_normal(Subdiv *subdiv,
-                                               const int ptex_face_index,
-                                               const float u,
-                                               const float v,
-                                               float r_P[3],
-                                               float r_N[3])
-{
-  if (subdiv->displacement_evaluator == NULL) {
-    BKE_subdiv_eval_limit_point_and_normal(subdiv, ptex_face_index, u, v, r_P, r_N);
-  }
-  else {
-    BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, r_P);
-  }
-}
-
 /** \} */
 
 /* -------------------------------------------------------------------- */
 /** \name Accumulation helpers
  * \{ */
 
-static void subdiv_accumulate_vertex_normal_and_displacement(SubdivMeshContext *ctx,
-                                                             const int ptex_face_index,
-                                                             const float u,
-                                                             const float v,
-                                                             MVert *subdiv_vert)
+static void subdiv_accumulate_vertex_displacement(SubdivMeshContext *ctx,
+                                                  const int ptex_face_index,
+                                                  const float u,
+                                                  const float v,
+                                                  MVert *subdiv_vert)
 {
   Subdiv *subdiv = ctx->subdiv;
   const int subdiv_vertex_index = subdiv_vert - ctx->subdiv_mesh->mvert;
   float dummy_P[3], dPdu[3], dPdv[3], D[3];
   BKE_subdiv_eval_limit_point_and_derivatives(subdiv, ptex_face_index, u, v, dummy_P, dPdu, dPdv);
-  /* Accumulate normal. */
-  if (ctx->can_evaluate_normals) {
-    float N[3];
-    cross_v3_v3v3(N, dPdu, dPdv);
-    normalize_v3(N);
-    add_v3_v3(ctx->accumulated_normals[subdiv_vertex_index], N);
-  }
+
   /* Accumulate displacement if needed. */
   if (ctx->have_displacement) {
     /* NOTE: The subdivided mesh is allocated in this module, and its vertices are kept at zero
@@ -616,12 +568,6 @@ static void evaluate_vertex_and_apply_displacement_interpolate(
   BKE_subdiv_eval_limit_point(ctx->subdiv, ptex_face_index, u, v, subdiv_vert->co);
   /* Apply displacement. */
   add_v3_v3(subdiv_vert->co, D);
-  /* Copy normal from accumulated storage. */
-  if (ctx->can_evaluate_normals) {
-    const float inv_num_accumulated = 1.0f / ctx->accumulated_counters[subdiv_vertex_index];
-    mul_v3_fl(ctx->accumulated_normals[subdiv_vertex_index], inv_num_accumulated);
-    normalize_v3(ctx->accumulated_normals[subdiv_vertex_index]);
-  }
 }
 
 static void subdiv_mesh_vertex_every_corner_or_edge(const SubdivForeachContext *foreach_context,
@@ -635,7 +581,7 @@ static void subdiv_mesh_vertex_every_corner_or_edge(const SubdivForeachContext *
   Mesh *subdiv_mesh = ctx->subdiv_mesh;
   MVert *subdiv_mvert = subdiv_mesh->mvert;
   MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
-  subdiv_accumulate_vertex_normal_and_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
+  subdiv_accumulate_vertex_displacement(ctx, ptex_face_index, u, v, subdiv_vert);
 }
 
 static void subdiv_mesh_vertex_every_corner(const SubdivForeachContext *foreach_context,
@@ -784,12 +730,7 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
   MVert *subdiv_vert = &subdiv_mvert[subdiv_vertex_index];
   subdiv_mesh_ensure_vertex_interpolation(ctx, tls, coarse_poly, coarse_corner);
   subdiv_vertex_data_interpolate(ctx, subdiv_vert, &tls->vertex_interpolation, u, v);
-  eval_final_point_and_vertex_normal(subdiv,
-                                     ptex_face_index,
-                                     u,
-                                     v,
-                                     subdiv_vert->co,
-                                     ctx->accumulated_normals[subdiv_vertex_index]);
+  BKE_subdiv_eval_final_point(subdiv, ptex_face_index, u, v, subdiv_vert->co);
   subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vert, u, v);
 }
 
@@ -1136,10 +1077,6 @@ static void subdiv_mesh_vertex_of_loose_edge(const struct SubdivForeachContext *
   /* TODO(sergey): This matches old behavior, but we can as well interpolate
    * it. Maybe even using vertex varying attributes. */
   subdiv_vertex->bweight = 0.0f;
-  /* Reset normal, initialize it in a similar way as edit mode does for a
-   * vertices adjacent to a loose edges.
-   * See `mesh_evaluate#mesh_calc_normals_vert_fallback` */
-  normalize_v3_v3(ctx->accumulated_normals[subdiv_vertex_index], subdiv_vertex->co);
 }
 
 /** \} */
@@ -1155,7 +1092,7 @@ static void setup_foreach_callbacks(const SubdivMeshContext *subdiv_context,
   /* General information. */
   foreach_context->topology_info = subdiv_mesh_topology_info;
   /* Every boundary geometry. Used for displacement and normals averaging. */
-  if (subdiv_context->can_evaluate_normals || subdiv_context->have_displacement) {
+  if (subdiv_context->have_displacement) {
     foreach_context->vertex_every_corner = subdiv_mesh_vertex_every_corner;
     foreach_context->vertex_every_edge = subdiv_mesh_vertex_every_edge;
   }
@@ -1205,8 +1142,6 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
   subdiv_context.coarse_mesh = coarse_mesh;
   subdiv_context.subdiv = subdiv;
   subdiv_context.have_displacement = (subdiv->displacement_evaluator != NULL);
-  subdiv_context.can_evaluate_normals = !subdiv_context.have_displacement &&
-                                        subdiv_context.subdiv->settings.is_adaptive;
   /* Multi-threaded traversal/evaluation. */
   BKE_subdiv_stats_begin(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH_GEOMETRY);
   SubdivForeachContext foreach_context;
@@ -1220,9 +1155,11 @@ Mesh *BKE_subdiv_to_mesh(Subdiv *subdiv,
   Mesh *result = subdiv_context.subdiv_mesh;
   // BKE_mesh_validate(result, true, true);
   BKE_subdiv_stats_end(&subdiv->stats, SUBDIV_STATS_SUBDIV_TO_MESH);
-  if (!subdiv_context.can_evaluate_normals) {
-    BKE_mesh_normals_tag_dirty(result);
-  }
+  /* Using normals from the limit surface gives different results than Blender's vertex normal
+   * calculation. Since vertex normals are supposed to be a consistent cache, don't bother
+   * calculating them here. The work may have been pointless anyway if the mesh is deformed or
+   * changed afterwards. */
+  BKE_mesh_normals_tag_dirty(result);
   /* Free used memory. */
   subdiv_mesh_context_free(&subdiv_context);
   return result;



More information about the Bf-blender-cvs mailing list