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:
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;