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:
-rw-r--r--source/blender/blenkernel/BKE_mesh_iterators.h5
-rw-r--r--source/blender/blenkernel/BKE_modifier.h1
-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
-rw-r--r--source/blender/draw/intern/draw_cache_impl_mesh.c125
-rw-r--r--source/blender/editors/space_view3d/view3d_iterators.c12
-rw-r--r--source/blender/makesdna/DNA_meshdata_types.h1
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),
};