Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2019-07-07 19:58:11 +0300
committerClément Foucault <foucault.clem@gmail.com>2019-07-08 19:09:52 +0300
commit226c6f086aa255bb71e554c860545bb435c06756 (patch)
tree4c60367f561d5ecc08bb912049f937034b76e21d /source/blender/blenkernel/intern
parent0a16519f5df0fa74623d48b7786f1db22651110a (diff)
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.
Diffstat (limited to 'source/blender/blenkernel/intern')
-rw-r--r--source/blender/blenkernel/intern/mesh_iterators.c48
-rw-r--r--source/blender/blenkernel/intern/modifier.c32
-rw-r--r--source/blender/blenkernel/intern/subdiv_mesh.c32
3 files changed, 110 insertions, 2 deletions
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;