diff options
-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 | ||||
-rw-r--r-- | source/blender/draw/intern/draw_cache_impl_mesh.c | 125 | ||||
-rw-r--r-- | source/blender/editors/space_view3d/view3d_iterators.c | 12 | ||||
-rw-r--r-- | source/blender/makesdna/DNA_meshdata_types.h | 1 |
8 files changed, 227 insertions, 29 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; 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_len_get_maybe_mapped(rdata); @@ -2757,12 +2791,32 @@ static void mesh_create_edit_facedots_select_id(MeshRenderData *rdata, GPUVertBu } else { const int *p_origindex = rdata->mapped.p_origindex; - for (int poly = 0; poly < poly_len; poly++) { - const int p_orig = p_origindex[poly]; - if (p_orig != ORIGINDEX_NONE) { - const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig); - if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { - *((uint *)GPU_vertbuf_raw_step(&idx_step)) = p_orig; + if (modifiers_usesSubsurfFacedots(scene, ob)) { + Mesh *me_cage = rdata->mapped.me_cage; + const MPoly *mpoly = me_cage->mpoly; + for (int p = 0; p < poly_len; p++, mpoly++) { + const int p_orig = p_origindex[p]; + if (p_orig != ORIGINDEX_NONE) { + const MLoop *mloop = me_cage->mloop + mpoly->loopstart; + for (int l = 0; l < mpoly->totloop; l++, mloop++) { + if (me_cage->mvert[mloop->v].flag & ME_VERT_FACEDOT) { + const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig); + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + *((uint *)GPU_vertbuf_raw_step(&idx_step)) = p_orig; + } + } + } + } + } + } + else { + for (int poly = 0; poly < poly_len; poly++) { + const int p_orig = p_origindex[poly]; + if (p_orig != ORIGINDEX_NONE) { + const BMFace *efa = BM_face_at_index(rdata->edit_bmesh->bm, p_orig); + if (!BM_elem_flag_test(efa, BM_ELEM_HIDDEN)) { + *((uint *)GPU_vertbuf_raw_step(&idx_step)) = p_orig; + } } } } @@ -3372,7 +3426,10 @@ static void mesh_create_loop_vcol(MeshRenderData *rdata, GPUVertBuf *vbo) #undef USE_COMP_MESH_DATA } -static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_facedots_pos_nor_data) +static void mesh_create_edit_facedots(MeshRenderData *rdata, + GPUVertBuf *vbo_facedots_pos_nor_data, + Scene *scene, + Object *ob) { const int poly_len = mesh_render_data_polys_len_get_maybe_mapped(rdata); const int verts_facedot_len = poly_len; @@ -3414,21 +3471,37 @@ static void mesh_create_edit_facedots(MeshRenderData *rdata, GPUVertBuf *vbo_fac } } else { -#if 0 /* TODO(fclem): Mapped facedots are not following the original face. */ - Mesh *me_cage = rdata->mapped.me_cage; - const MVert *mvert = me_cage->mvert; - const MEdge *medge = me_cage->medge; - const int *e_origindex = rdata->mapped.e_origindex; - const int *v_origindex = rdata->mapped.v_origindex; -#endif - for (int i = 0; i < poly_len; i++) { - if (add_edit_facedot_mapped(rdata, - vbo_facedots_pos_nor_data, - attr_id.fdot_pos, - attr_id.fdot_nor_flag, - i, - facedot_len_used)) { - facedot_len_used += 1; + if (modifiers_usesSubsurfFacedots(scene, ob)) { + /* Facedots that follow surbsurf face center. */ + Mesh *me_cage = rdata->mapped.me_cage; + const MPoly *mpoly = me_cage->mpoly; + for (int p = 0; p < poly_len; p++, mpoly++) { + const MLoop *mloop = me_cage->mloop + mpoly->loopstart; + for (int l = 0; l < mpoly->totloop; l++, mloop++) { + if (me_cage->mvert[mloop->v].flag & ME_VERT_FACEDOT) { + if (add_edit_facedot_subdiv(rdata, + vbo_facedots_pos_nor_data, + attr_id.fdot_pos, + attr_id.fdot_nor_flag, + mloop->v, + p, + facedot_len_used)) { + facedot_len_used += 1; + } + } + } + } + } + else { + for (int i = 0; i < poly_len; i++) { + if (add_edit_facedot_mapped(rdata, + vbo_facedots_pos_nor_data, + attr_id.fdot_pos, + attr_id.fdot_nor_flag, + i, + facedot_len_used)) { + facedot_len_used += 1; + } } } } @@ -5447,10 +5520,12 @@ void DRW_mesh_batch_cache_create_requested( cache->edit.loop_face_idx); } if (DRW_vbo_requested(cache->edit.facedots_pos_nor_data)) { - mesh_create_edit_facedots(rdata, cache->edit.facedots_pos_nor_data); + Scene *scene = DRW_context_state_get()->scene; + mesh_create_edit_facedots(rdata, cache->edit.facedots_pos_nor_data, scene, ob); } if (DRW_vbo_requested(cache->edit.facedots_idx)) { - mesh_create_edit_facedots_select_id(rdata, cache->edit.facedots_idx); + Scene *scene = DRW_context_state_get()->scene; + mesh_create_edit_facedots_select_id(rdata, cache->edit.facedots_idx, scene, ob); } if (DRW_ibo_requested(cache->ibo.edit_loops_points) || DRW_ibo_requested(cache->ibo.edit_loops_lines)) { diff --git a/source/blender/editors/space_view3d/view3d_iterators.c b/source/blender/editors/space_view3d/view3d_iterators.c index 6ed0508f09f..2636062ed8b 100644 --- a/source/blender/editors/space_view3d/view3d_iterators.c +++ b/source/blender/editors/space_view3d/view3d_iterators.c @@ -38,6 +38,7 @@ #include "BKE_editmesh.h" #include "BKE_mesh_runtime.h" #include "BKE_mesh_iterators.h" +#include "BKE_modifier.h" #include "DEG_depsgraph.h" #include "DEG_depsgraph_query.h" @@ -293,8 +294,15 @@ void mesh_foreachScreenFace( data.clip_flag = clip_flag; BM_mesh_elem_table_ensure(vc->em->bm, BM_FACE); - BKE_mesh_foreach_mapped_face_center( - me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); + + if (modifiers_usesSubsurfFacedots(vc->scene, vc->obedit)) { + BKE_mesh_foreach_mapped_subdiv_face_center( + me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); + } + else { + BKE_mesh_foreach_mapped_face_center( + me, mesh_foreachScreenFace__mapFunc, &data, MESH_FOREACH_NOP); + } } /* ------------------------------------------------------------------------ */ diff --git a/source/blender/makesdna/DNA_meshdata_types.h b/source/blender/makesdna/DNA_meshdata_types.h index 04d060b065d..88eef05f8be 100644 --- a/source/blender/makesdna/DNA_meshdata_types.h +++ b/source/blender/makesdna/DNA_meshdata_types.h @@ -394,6 +394,7 @@ enum { /* SELECT = (1 << 0), */ ME_VERT_TMP_TAG = (1 << 2), ME_HIDE = (1 << 4), + ME_VERT_FACEDOT = (1 << 5), /* ME_VERT_MERGED = (1 << 6), */ ME_VERT_PBVH_UPDATE = (1 << 7), }; |