[Bf-blender-cvs] [226c6f086aa] master: Fix T62941 Subdivision Modifier Showing all face dots

Clément Foucault noreply at git.blender.org
Mon Jul 8 18:18:49 CEST 2019


Commit: 226c6f086aa255bb71e554c860545bb435c06756
Author: Clément Foucault
Date:   Sun Jul 7 18:58:11 2019 +0200
Branches: master
https://developer.blender.org/rB226c6f086aa255bb71e554c860545bb435c06756

Fix T62941 Subdivision Modifier Showing all face dots

Previously in 2.79 we were using a specialized drawing using derivedMesh.

Now the subsurf modifier tag each center vertex as facedot and let the
DRWManager pick it up.

Some modifiers (deforming ones) do not clear the tag so we can use this
technique even if there is deforming modifiers after subsurf modifiers.

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

M	source/blender/blenkernel/BKE_mesh_iterators.h
M	source/blender/blenkernel/BKE_modifier.h
M	source/blender/blenkernel/intern/mesh_iterators.c
M	source/blender/blenkernel/intern/modifier.c
M	source/blender/blenkernel/intern/subdiv_mesh.c
M	source/blender/draw/intern/draw_cache_impl_mesh.c
M	source/blender/editors/space_view3d/view3d_iterators.c
M	source/blender/makesdna/DNA_meshdata_types.h

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

diff --git a/source/blender/blenkernel/BKE_mesh_iterators.h b/source/blender/blenkernel/BKE_mesh_iterators.h
index 7bbd64c0bac..28fd4b8bc28 100644
--- a/source/blender/blenkernel/BKE_mesh_iterators.h
+++ b/source/blender/blenkernel/BKE_mesh_iterators.h
@@ -59,6 +59,11 @@ void BKE_mesh_foreach_mapped_face_center(
     void (*func)(void *userData, int index, const float cent[3], const float no[3]),
     void *userData,
     MeshForeachFlag flag);
+void BKE_mesh_foreach_mapped_subdiv_face_center(
+    struct Mesh *mesh,
+    void (*func)(void *userData, int index, const float cent[3], const float no[3]),
+    void *userData,
+    MeshForeachFlag flag);
 
 void BKE_mesh_foreach_mapped_vert_coords_get(struct Mesh *me_eval,
                                              float (*r_cos)[3],
diff --git a/source/blender/blenkernel/BKE_modifier.h b/source/blender/blenkernel/BKE_modifier.h
index 30a366805b6..4aab2a346e7 100644
--- a/source/blender/blenkernel/BKE_modifier.h
+++ b/source/blender/blenkernel/BKE_modifier.h
@@ -382,6 +382,7 @@ struct Object *modifiers_isDeformedByMeshDeform(struct Object *ob);
 struct Object *modifiers_isDeformedByLattice(struct Object *ob);
 struct Object *modifiers_isDeformedByCurve(struct Object *ob);
 bool modifiers_usesArmature(struct Object *ob, struct bArmature *arm);
+bool modifiers_usesSubsurfFacedots(struct Scene *scene, struct Object *ob);
 bool modifiers_isCorrectableDeformed(struct Scene *scene, struct Object *ob);
 void modifier_freeTemporaryData(struct ModifierData *md);
 bool modifiers_isPreview(struct Object *ob);
diff --git a/source/blender/blenkernel/intern/mesh_iterators.c b/source/blender/blenkernel/intern/mesh_iterators.c
index df6517066b8..f2ed9456b11 100644
--- a/source/blender/blenkernel/intern/mesh_iterators.c
+++ b/source/blender/blenkernel/intern/mesh_iterators.c
@@ -180,6 +180,54 @@ void BKE_mesh_foreach_mapped_face_center(
   }
 }
 
+/* Copied from cdDM_foreachMappedFaceCenter */
+void BKE_mesh_foreach_mapped_subdiv_face_center(
+    Mesh *mesh,
+    void (*func)(void *userData, int index, const float cent[3], const float no[3]),
+    void *userData,
+    MeshForeachFlag flag)
+{
+  const MPoly *mp = mesh->mpoly;
+  const MLoop *ml;
+  const MVert *mv;
+  float _no_buf[3];
+  float *no = (flag & MESH_FOREACH_USE_NORMAL) ? _no_buf : NULL;
+  const int *index = CustomData_get_layer(&mesh->pdata, CD_ORIGINDEX);
+
+  if (index) {
+    for (int i = 0; i < mesh->totpoly; i++, mp++) {
+      const int orig = *index++;
+      if (orig == ORIGINDEX_NONE) {
+        continue;
+      }
+      ml = &mesh->mloop[mp->loopstart];
+      for (int j = 0; j < mp->totloop; j++, ml++) {
+        mv = &mesh->mvert[ml->v];
+        if (mv->flag & ME_VERT_FACEDOT) {
+          if (flag & MESH_FOREACH_USE_NORMAL) {
+            normal_short_to_float_v3(no, mv->no);
+          }
+          func(userData, orig, mv->co, no);
+        }
+      }
+    }
+  }
+  else {
+    for (int i = 0; i < mesh->totpoly; i++, mp++) {
+      ml = &mesh->mloop[mp->loopstart];
+      for (int j = 0; j < mp->totloop; j++, ml++) {
+        mv = &mesh->mvert[ml->v];
+        if (mv->flag & ME_VERT_FACEDOT) {
+          if (flag & MESH_FOREACH_USE_NORMAL) {
+            normal_short_to_float_v3(no, mv->no);
+          }
+          func(userData, i, mv->co, no);
+        }
+      }
+    }
+  }
+}
+
 /* Helpers based on above foreach loopers> */
 
 typedef struct MappedVCosData {
diff --git a/source/blender/blenkernel/intern/modifier.c b/source/blender/blenkernel/intern/modifier.c
index 2254207e545..d547449aa60 100644
--- a/source/blender/blenkernel/intern/modifier.c
+++ b/source/blender/blenkernel/intern/modifier.c
@@ -778,6 +778,38 @@ bool modifiers_usesArmature(Object *ob, bArmature *arm)
   return false;
 }
 
+bool modifiers_usesSubsurfFacedots(struct Scene *scene, Object *ob)
+{
+  /* Search (backward) in the modifier stack to find if we have a subsurf modifier (enabled) before
+   * the last modifier displayed on cage (or if the subsurf is the last). */
+  VirtualModifierData virtualModifierData;
+  ModifierData *md = modifiers_getVirtualModifierList(ob, &virtualModifierData);
+  int cage_index = modifiers_getCageIndex(scene, ob, NULL, 1);
+  /* Find first modifier enabled on cage. */
+  for (int i; md && i < cage_index; i++) {
+    md = md->next;
+  }
+  /* Now from this point, search for subsurf modifier. */
+  for (; md; md = md->prev) {
+    const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
+    if (md->type == eModifierType_Subsurf) {
+      ModifierMode mode = eModifierMode_Realtime | eModifierMode_Editmode;
+      if (modifier_isEnabled(scene, md, mode)) {
+        return true;
+      }
+    }
+    else if (mti->type == eModifierTypeType_OnlyDeform) {
+      /* Theses modifiers do not reset the subdiv flag nor change the topology.
+       * We can still search for a subsurf modifier. */
+    }
+    else {
+      /* Other modifiers may reset the subdiv facedot flag or create. */
+      return false;
+    }
+  }
+  return false;
+}
+
 bool modifier_isCorrectableDeformed(ModifierData *md)
 {
   const ModifierTypeInfo *mti = modifierType_getInfo(md->type);
diff --git a/source/blender/blenkernel/intern/subdiv_mesh.c b/source/blender/blenkernel/intern/subdiv_mesh.c
index 947f51b4ff9..75e05f8ffab 100644
--- a/source/blender/blenkernel/intern/subdiv_mesh.c
+++ b/source/blender/blenkernel/intern/subdiv_mesh.c
@@ -570,6 +570,8 @@ static void evaluate_vertex_and_apply_displacement_copy(const SubdivMeshContext
     normalize_v3(N);
     normal_float_to_short_v3(subdiv_vert->no, N);
   }
+  /* Remove facedot flag. This can happen if there is more than one subsurf modifier. */
+  subdiv_vert->flag &= ~ME_VERT_FACEDOT;
 }
 
 static void evaluate_vertex_and_apply_displacement_interpolate(
@@ -719,6 +721,31 @@ static void subdiv_mesh_vertex_edge(const SubdivForeachContext *foreach_context,
       ctx, ptex_face_index, u, v, &tls->vertex_interpolation, subdiv_vert);
 }
 
+static bool subdiv_mesh_is_center_vertex(const MPoly *coarse_poly, const float u, const float v)
+{
+  if (coarse_poly->totloop == 4) {
+    if (u == 0.5f && v == 0.5f) {
+      return true;
+    }
+  }
+  else {
+    if (u == 1.0f && v == 1.0f) {
+      return true;
+    }
+  }
+  return false;
+}
+
+static void subdiv_mesh_tag_center_vertex(const MPoly *coarse_poly,
+                                          MVert *subdiv_vert,
+                                          const float u,
+                                          const float v)
+{
+  if (subdiv_mesh_is_center_vertex(coarse_poly, u, v)) {
+    subdiv_vert->flag |= ME_VERT_FACEDOT;
+  }
+}
+
 static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context,
                                      void *tls_v,
                                      const int ptex_face_index,
@@ -741,6 +768,7 @@ static void subdiv_mesh_vertex_inner(const SubdivForeachContext *foreach_context
   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, subdiv_vert->no);
+  subdiv_mesh_tag_center_vertex(coarse_poly, subdiv_vert, u, v);
 }
 
 /* =============================================================================
@@ -1098,8 +1126,8 @@ static void setup_foreach_callbacks(const SubdivMeshContext *subdiv_context,
     foreach_context->vertex_every_edge = subdiv_mesh_vertex_every_edge;
   }
   else {
-    foreach_context->vertex_every_corner = NULL;
-    foreach_context->vertex_every_edge = NULL;
+    foreach_context->vertex_every_corner = subdiv_mesh_vertex_every_corner;
+    foreach_context->vertex_every_edge = subdiv_mesh_vertex_every_edge;
   }
   foreach_context->vertex_corner = subdiv_mesh_vertex_corner;
   foreach_context->vertex_edge = subdiv_mesh_vertex_edge;
diff --git a/source/blender/draw/intern/draw_cache_impl_mesh.c b/source/blender/draw/intern/draw_cache_impl_mesh.c
index 1ebdab19375..c70c0aac662 100644
--- a/source/blender/draw/intern/draw_cache_impl_mesh.c
+++ b/source/blender/draw/intern/draw_cache_impl_mesh.c
@@ -47,6 +47,7 @@
 #include "BKE_mesh.h"
 #include "BKE_mesh_tangent.h"
 #include "BKE_mesh_runtime.h"
+#include "BKE_modifier.h"
 #include "BKE_object_deform.h"
 
 #include "atomic_ops.h"
@@ -1813,6 +1814,36 @@ static bool add_edit_facedot_mapped(MeshRenderData *rdata,
 
   return true;
 }
+static bool add_edit_facedot_subdiv(MeshRenderData *rdata,
+                                    GPUVertBuf *vbo,
+                                    const uint fdot_pos_id,
+                                    const uint fdot_nor_flag_id,
+                                    const int vert,
+                                    const int poly,
+                                    const int base_vert_idx)
+{
+  BLI_assert(rdata->types & (MR_DATATYPE_VERT | MR_DATATYPE_LOOP | MR_DATATYPE_POLY));
+  const int *p_origindex = rdata->mapped.p_origindex;
+  const int p_orig = p_origindex[poly];
+  if (p_orig == ORIGINDEX_NONE) {
+    return false;
+  }
+  BMEditMesh *em = rdata->edit_bmesh;
+  const BMFace *efa = BM_face_at_index(em->bm, p_orig);
+  if (BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) {
+    return false;
+  }
+
+  Mesh *me_cage = em->mesh_eval_cage;
+  const MVert *mvert = &me_cage->mvert[vert];
+
+  GPUPackedNormal nor = GPU_normal_convert_i10_s3(mvert->no);
+  nor.w = BM_elem_flag_test(efa, BM_ELEM_SELECT) ? ((efa == em->bm->act_face) ? -1 : 1) : 0;
+  GPU_vertbuf_attr_set(vbo, fdot_nor_flag_id, base_vert_idx, &nor);
+  GPU_vertbuf_attr_set(vbo, fdot_pos_id, base_vert_idx, mvert->co);
+
+  return true;
+}
 
 /** \} */
 
@@ -2722,7 +2753,10 @@ static void mesh_create_edit_vertex_loops(MeshRenderData *rdata,
 }
 
 /* TODO: We could use gl_PrimitiveID as index instead of using another VBO. */
-static void mesh_create_edit_facedots_select_id(MeshRenderData *rdata, GPUVertBuf *vbo)
+static void mesh_create_edit_facedots_select_id(MeshRenderData *rdata,
+                                                GPUVertBuf *vbo,
+                                                Scene *scene,
+                                                Object *ob)
 {
   const int poly_len = mesh_render_data_polys_

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list