diff options
Diffstat (limited to 'source/blender/blenkernel')
-rw-r--r-- | source/blender/blenkernel/BKE_mesh_iterators.h | 5 | ||||
-rw-r--r-- | source/blender/blenkernel/BKE_modifier.h | 1 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/mesh_iterators.c | 48 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/modifier.c | 32 | ||||
-rw-r--r-- | source/blender/blenkernel/intern/subdiv_mesh.c | 32 |
5 files changed, 116 insertions, 2 deletions
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; |