[Bf-blender-cvs] [baa34974ef7] tmp-batch-cache-cleanup: UVEdit: Support Mesh eval cage selection

Clément Foucault noreply at git.blender.org
Mon Jul 22 12:53:10 CEST 2019


Commit: baa34974ef74bc11dd8302298e35cf88675247e3
Author: Clément Foucault
Date:   Sun Jul 21 12:00:41 2019 +0200
Branches: tmp-batch-cache-cleanup
https://developer.blender.org/rBbaa34974ef74bc11dd8302298e35cf88675247e3

UVEdit: Support Mesh eval cage selection

- Select Vert / Edge / Face support
- TODO : Rect / Lasso / Circle / Loop

===================================================================

M	source/blender/editors/sculpt_paint/sculpt_uv.c
M	source/blender/editors/uvedit/uvedit_intern.h
M	source/blender/editors/uvedit/uvedit_ops.c
M	source/blender/editors/uvedit/uvedit_smart_stitch.c

===================================================================

diff --git a/source/blender/editors/sculpt_paint/sculpt_uv.c b/source/blender/editors/sculpt_paint/sculpt_uv.c
index 36cc3605273..f995b28cac3 100644
--- a/source/blender/editors/sculpt_paint/sculpt_uv.c
+++ b/source/blender/editors/sculpt_paint/sculpt_uv.c
@@ -488,6 +488,7 @@ static bool uv_edge_compare(const void *a, const void *b)
 
 static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wmEvent *event)
 {
+  Depsgraph *depsgraph = CTX_data_depsgraph(C);
   Scene *scene = CTX_data_scene(C);
   Object *obedit = CTX_data_edit_object(C);
   ToolSettings *ts = scene->toolsettings;
@@ -554,7 +555,7 @@ static UvSculptData *uv_sculpt_stroke_init(bContext *C, wmOperator *op, const wm
       UvElement *element;
       UvNearestHit hit = UV_NEAREST_HIT_INIT;
       Image *ima = CTX_data_edit_image(C);
-      uv_find_nearest_vert(scene, ima, obedit, co, 0.0f, &hit);
+      uv_find_nearest_vert(depsgraph, scene, ima, obedit, co, 0.0f, &hit);
 
       element = BM_uv_element_get(data->elementMap, hit.efa, hit.l);
       island_index = element->island;
diff --git a/source/blender/editors/uvedit/uvedit_intern.h b/source/blender/editors/uvedit/uvedit_intern.h
index 3f544ad90d1..333996a2bf1 100644
--- a/source/blender/editors/uvedit/uvedit_intern.h
+++ b/source/blender/editors/uvedit/uvedit_intern.h
@@ -57,13 +57,15 @@ typedef struct UvNearestHit {
     .dist_sq = FLT_MAX, \
   }
 
-bool uv_find_nearest_vert(struct Scene *scene,
+bool uv_find_nearest_vert(struct Depsgraph *depsgraph,
+                          struct Scene *scene,
                           struct Image *ima,
                           struct Object *obedit,
                           const float co[2],
                           const float penalty_dist,
                           struct UvNearestHit *hit_final);
-bool uv_find_nearest_vert_multi(struct Scene *scene,
+bool uv_find_nearest_vert_multi(struct Depsgraph *depsgraph,
+                                struct Scene *scene,
                                 struct Image *ima,
                                 struct Object **objects,
                                 const uint objects_len,
@@ -71,24 +73,28 @@ bool uv_find_nearest_vert_multi(struct Scene *scene,
                                 const float penalty_dist,
                                 struct UvNearestHit *hit_final);
 
-bool uv_find_nearest_edge(struct Scene *scene,
+bool uv_find_nearest_edge(struct Depsgraph *depsgraph,
+                          struct Scene *scene,
                           struct Image *ima,
                           struct Object *obedit,
                           const float co[2],
                           struct UvNearestHit *hit_final);
-bool uv_find_nearest_edge_multi(struct Scene *scene,
+bool uv_find_nearest_edge_multi(struct Depsgraph *depsgraph,
+                                struct Scene *scene,
                                 struct Image *ima,
                                 struct Object **objects,
                                 const uint objects_len,
                                 const float co[2],
                                 struct UvNearestHit *hit_final);
 
-bool uv_find_nearest_face(struct Scene *scene,
+bool uv_find_nearest_face(struct Depsgraph *depsgraph,
+                          struct Scene *scene,
                           struct Image *ima,
                           struct Object *obedit,
                           const float co[2],
                           struct UvNearestHit *hit_final);
-bool uv_find_nearest_face_multi(struct Scene *scene,
+bool uv_find_nearest_face_multi(struct Depsgraph *depsgraph,
+                                struct Scene *scene,
                                 struct Image *ima,
                                 struct Object **objects,
                                 const uint objects_len,
diff --git a/source/blender/editors/uvedit/uvedit_ops.c b/source/blender/editors/uvedit/uvedit_ops.c
index 71bf6a1946a..106df7d30ae 100644
--- a/source/blender/editors/uvedit/uvedit_ops.c
+++ b/source/blender/editors/uvedit/uvedit_ops.c
@@ -56,6 +56,7 @@
 #include "BKE_material.h"
 #include "BKE_mesh.h"
 #include "BKE_mesh_mapping.h"
+#include "BKE_modifier.h"
 #include "BKE_node.h"
 #include "BKE_report.h"
 #include "BKE_scene.h"
@@ -606,6 +607,18 @@ void uv_poly_center(BMFace *f, float r_cent[2], const int cd_loop_uv_offset)
   mul_v2_fl(r_cent, 1.0f / (float)f->len);
 }
 
+static void uv_mpoly_center(const MPoly *mpoly, const MLoopUV *mloopuv, float r_cent[2])
+{
+  zero_v2(r_cent);
+
+  for (int i = 0; i < mpoly->totloop; i++) {
+    const MLoopUV *luv = &mloopuv[mpoly->loopstart + i];
+    add_v2_v2(r_cent, luv->uv);
+  }
+
+  mul_v2_fl(r_cent, 1.0f / (float)mpoly->totloop);
+}
+
 void uv_poly_copy_aspect(float uv_orig[][2], float uv[][2], float aspx, float aspy, int len)
 {
   int i;
@@ -753,8 +766,12 @@ bool ED_uvedit_center(Scene *scene, Image *ima, Object *obedit, float cent[2], c
 /** \name Find Nearest Elements
  * \{ */
 
-bool uv_find_nearest_edge(
-    Scene *scene, Image *ima, Object *obedit, const float co[2], UvNearestHit *hit)
+bool uv_find_nearest_edge(Depsgraph *depsgraph,
+                          Scene *scene,
+                          Image *ima,
+                          Object *obedit,
+                          const float co[2],
+                          UvNearestHit *hit)
 {
   BMEditMesh *em = BKE_editmesh_from_object(obedit);
   BMFace *efa;
@@ -766,35 +783,85 @@ bool uv_find_nearest_edge(
 
   const int cd_loop_uv_offset = CustomData_get_offset(&em->bm->ldata, CD_MLOOPUV);
 
-  BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+  /* (fclem) Is it garanteed that obedit_eval will be updated? */
+  Object *obedit_eval = DEG_get_evaluated_object(depsgraph, obedit);
+  BMEditMesh *em_eval = BKE_editmesh_from_object(obedit_eval);
 
-  BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
-    if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
-      continue;
+  if (!em_eval->mesh_eval_cage || em_eval->mesh_eval_cage->runtime.is_original) {
+    BM_mesh_elem_index_ensure(em->bm, BM_VERT);
+
+    BM_ITER_MESH (efa, &iter, em->bm, BM_FACES_OF_MESH) {
+      if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+        continue;
+      }
+      BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
+        luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
+        luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+
+        const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
+
+        if (dist_test_sq < hit->dist_sq) {
+          hit->efa = efa;
+
+          hit->l = l;
+          hit->luv = luv;
+          hit->luv_next = luv_next;
+          hit->lindex = i;
+
+          hit->dist_sq = dist_test_sq;
+          found = true;
+        }
+      }
     }
-    BM_ITER_ELEM_INDEX (l, &liter, efa, BM_LOOPS_OF_FACE, i) {
-      luv = BM_ELEM_CD_GET_VOID_P(l, cd_loop_uv_offset);
-      luv_next = BM_ELEM_CD_GET_VOID_P(l->next, cd_loop_uv_offset);
+  }
+  else {
+    Mesh *me = em_eval->mesh_eval_cage;
 
-      const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
+    BM_mesh_elem_table_ensure(em->bm, BM_FACE | BM_EDGE);
 
-      if (dist_test_sq < hit->dist_sq) {
-        hit->efa = efa;
+    int *p_origindex = CustomData_get_layer(&me->pdata, CD_ORIGINDEX);
+    int *e_origindex = CustomData_get_layer(&me->edata, CD_ORIGINDEX);
 
-        hit->l = l;
-        hit->luv = luv;
-        hit->luv_next = luv_next;
-        hit->lindex = i;
+    MLoopUV *mluv = CustomData_get_layer(&me->ldata, CD_MLOOPUV);
 
-        hit->dist_sq = dist_test_sq;
-        found = true;
+    MPoly *mpoly = me->mpoly;
+    for (int p = 0; p < me->totpoly; p++, mpoly++) {
+      if (p_origindex[p] == ORIGINDEX_NONE) {
+        continue;
+      }
+      efa = BM_face_at_index(em->bm, p_origindex[p]);
+      if (!uvedit_face_visible_test(scene, obedit, ima, efa)) {
+        continue;
+      }
+      for (i = 0; i < mpoly->totloop; i++) {
+        MLoop *mloop = &me->mloop[mpoly->loopstart + i];
+        if (e_origindex[mloop->e] == ORIGINDEX_NONE) {
+          continue;
+        }
+        luv = &mluv[mpoly->loopstart + i];
+        luv_next = &mluv[mpoly->loopstart + ((i + 1) % mpoly->totloop)];
+        const float dist_test_sq = dist_squared_to_line_segment_v2(co, luv->uv, luv_next->uv);
+
+        if (dist_test_sq < hit->dist_sq) {
+          BMEdge *eed = BM_edge_at_index(em->bm, e_origindex[mloop->e]);
+          hit->efa = efa;
+
+          hit->l = BM_face_edge_share_loop(efa, eed);
+          hit->luv = luv;
+          hit->luv_next = luv_next;
+          hit->lindex = i;
+
+          hit->dist_sq = dist_test_sq;
+          found = true;
+        }
       }
     }
   }
   return found;
 }
 
-bool uv_find_nearest_edge_multi(Scene *scene,
+bool uv_find_nearest_edge_multi(Depsgraph *depsgraph,
+                                Scene *scene,
                                 Image *ima,
                                 Object **objects,
                                 const uint objects_len,
@@ -804,7 +871,7 @@ bool uv_find_nearest_edge_multi(Scene *scene,
   bool found = false;
   for (uint ob_index = 0; ob_index < objects_len; ob_index++) {
     Object *obedit = objects[ob_index];
-    if (uv_find_nearest_edge(scene, ima, obedit, co, hit_final)) {
+    if (uv_find_nearest_edge(depsgraph, scene, ima, obedit, co, hit_final)) {
       hit_final->ob = obedit;
       found = true;
     }
@@ -812,8 +879,12 @@ bool uv_find_nearest_edge_multi(Scene *scene,
   return found;
 }
 
-bool uv_find_nearest_face(
-    Scene *scene, Image *ima, Object *obedit, const float co[2], UvNearestHit *hit_final)
+bool uv_find_nearest_face(Depsgraph *depsgraph,
+                          Scene *scene,
+                          Image *ima,
+                          Object *obedit,
+                          const float co[2],
+                          UvNearestHit *hit_final)
 {
   BMEditMesh *em = BKE_editmesh_from_object(obedit);
   bool found = false;
@@ -823,28 +894,94 @@ bool uv_find_nearest_face(
   /* this will fill in hit.vert1 and hit.vert2 */
   float dist_sq_init = hit_final->dist_sq;


@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list