Commit: 3aa4a0e787993ddecaff30f36c502af20250837e
Author: Campbell Barton
Date:   Sat May 16 12:21:31 2015 +1000
Branches: master
https://developer.blender.org/rB3aa4a0e787993ddecaff30f36c502af20250837e

BMesh: add UV delimit for select-linked, dissolve

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

M       source/blender/bmesh/intern/bmesh_operator_api.h
M       source/blender/bmesh/intern/bmesh_queries.c
M       source/blender/bmesh/intern/bmesh_queries.h
M       source/blender/bmesh/tools/bmesh_decimate.h
M       source/blender/bmesh/tools/bmesh_decimate_dissolve.c
M       source/blender/editors/mesh/editmesh_select.c
M       source/blender/makesrna/intern/rna_mesh.c

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

diff --git a/source/blender/bmesh/intern/bmesh_operator_api.h 
b/source/blender/bmesh/intern/bmesh_operator_api.h
index 917b9a9..3f7fb7b 100644
--- a/source/blender/bmesh/intern/bmesh_operator_api.h
+++ b/source/blender/bmesh/intern/bmesh_operator_api.h
@@ -303,6 +303,7 @@ typedef enum {
        BMO_DELIM_MATERIAL = 1 << 1,
        BMO_DELIM_SEAM = 1 << 2,
        BMO_DELIM_SHARP = 1 << 3,
+       BMO_DELIM_UV = 1 << 4,
 } BMO_Delimit;
 
 void BMO_op_flag_enable(BMesh *bm, BMOperator *op, const int op_flag);
diff --git a/source/blender/bmesh/intern/bmesh_queries.c 
b/source/blender/bmesh/intern/bmesh_queries.c
index 9bc4502..4fbba5a 100644
--- a/source/blender/bmesh/intern/bmesh_queries.c
+++ b/source/blender/bmesh/intern/bmesh_queries.c
@@ -38,6 +38,8 @@
 #include "BLI_linklist.h"
 #include "BLI_stackdefines.h"
 
+#include "BKE_customdata.h"
+
 #include "bmesh.h"
 #include "intern/bmesh_private.h"
 
@@ -1039,6 +1041,53 @@ bool BM_edge_is_convex(const BMEdge *e)
        return true;
 }
 
+/**
+ * Returms true when loop customdata is contiguous.
+ */
+bool BM_edge_is_contiguous_loop_cd(
+        const BMEdge *e,
+        const int cd_loop_type, const int cd_loop_offset)
+{
+       BLI_assert(cd_loop_offset != -1);
+
+       if (e->l && e->l->radial_next != e->l) {
+               const BMLoop *l_base_v1 = e->l;
+               const BMLoop *l_base_v2 = e->l->next;
+               const void *l_base_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_base_v1, 
cd_loop_offset);
+               const void *l_base_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_base_v2, 
cd_loop_offset);
+               const BMLoop *l_iter = e->l->radial_next;
+               do {
+                       const BMLoop *l_iter_v1;
+                       const BMLoop *l_iter_v2;
+                       const void *l_iter_cd_v1;
+                       const void *l_iter_cd_v2;
+
+                       if (l_iter->v == l_base_v1->v) {
+                               l_iter_v1 = l_iter;
+                               l_iter_v2 = l_iter->next;
+                       }
+                       else {
+                               l_iter_v1 = l_iter->next;
+                               l_iter_v2 = l_iter;
+                       }
+                       BLI_assert((l_iter_v1->v == l_base_v1->v) &&
+                                  (l_iter_v2->v == l_base_v2->v));
+
+                       l_iter_cd_v1 = BM_ELEM_CD_GET_VOID_P(l_iter_v1, 
cd_loop_offset);
+                       l_iter_cd_v2 = BM_ELEM_CD_GET_VOID_P(l_iter_v2, 
cd_loop_offset);
+
+
+                       if ((CustomData_data_equals(cd_loop_type, l_base_cd_v1, 
l_iter_cd_v1) == 0) ||
+                           (CustomData_data_equals(cd_loop_type, l_base_cd_v2, 
l_iter_cd_v2) == 0))
+                       {
+                               return false;
+                       }
+
+               } while ((l_iter = l_iter->radial_next) != e->l);
+       }
+       return true;
+}
+
 bool BM_vert_is_boundary(const BMVert *v)
 {
        if (v->e) {
diff --git a/source/blender/bmesh/intern/bmesh_queries.h 
b/source/blender/bmesh/intern/bmesh_queries.h
index f0a348d..d66bd00 100644
--- a/source/blender/bmesh/intern/bmesh_queries.h
+++ b/source/blender/bmesh/intern/bmesh_queries.h
@@ -91,6 +91,10 @@ bool    BM_vert_is_boundary(const BMVert *v) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNUL
 BLI_INLINE bool    BM_edge_is_boundary(const BMEdge *e) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 BLI_INLINE bool    BM_edge_is_contiguous(const BMEdge *e) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 bool    BM_edge_is_convex(const BMEdge *e) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL();
+bool    BM_edge_is_contiguous_loop_cd(
+        const BMEdge *e,
+        const int cd_loop_type, const int cd_loop_offset)
+        ATTR_WARN_UNUSED_RESULT ATTR_NONNULL();
 
 int     BM_loop_region_loops_count_ex(BMLoop *l, int *r_loop_total) 
ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1);
 int     BM_loop_region_loops_count(BMLoop *l) ATTR_WARN_UNUSED_RESULT 
ATTR_NONNULL(1);
diff --git a/source/blender/bmesh/tools/bmesh_decimate.h 
b/source/blender/bmesh/tools/bmesh_decimate.h
index 1efa829..17b55be 100644
--- a/source/blender/bmesh/tools/bmesh_decimate.h
+++ b/source/blender/bmesh/tools/bmesh_decimate.h
@@ -34,7 +34,7 @@ void BM_mesh_decimate_unsubdivide(BMesh *bm, const int 
iterations);
 
 void BM_mesh_decimate_dissolve_ex(
         BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
-        const BMO_Delimit delimit,
+        BMO_Delimit delimit,
         BMVert **vinput_arr, const int vinput_len,
         BMEdge **einput_arr, const int einput_len,
         const short oflag_out);
diff --git a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c 
b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
index 8a14291..986e464 100644
--- a/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
+++ b/source/blender/bmesh/tools/bmesh_decimate_dissolve.c
@@ -32,6 +32,8 @@
 #include "BLI_math.h"
 #include "BLI_heap.h"
 
+#include "BKE_customdata.h"
+
 #include "bmesh.h"
 #include "bmesh_decimate.h"  /* own include */
 
@@ -59,7 +61,32 @@ static float bm_vert_edge_face_angle(BMVert *v)
 #undef ANGLE_TO_UNIT
 }
 
-static float bm_edge_calc_dissolve_error(const BMEdge *e, const BMO_Delimit 
delimit)
+struct DelimitData {
+       int cd_loop_type;
+       int cd_loop_size;
+       int cd_loop_offset;
+       int cd_loop_offset_end;
+};
+
+static bool bm_edge_is_contiguous_loop_cd_all(
+        const BMEdge *e, const struct DelimitData *delimit_data)
+{
+       int cd_loop_offset;
+       for (cd_loop_offset = delimit_data->cd_loop_offset;
+            cd_loop_offset < delimit_data->cd_loop_offset_end;
+            cd_loop_offset += delimit_data->cd_loop_size)
+       {
+               if (BM_edge_is_contiguous_loop_cd(e, 
delimit_data->cd_loop_type, cd_loop_offset) == false) {
+                       return false;
+               }
+       }
+
+       return true;
+}
+
+static float bm_edge_calc_dissolve_error(
+        const BMEdge *e, const BMO_Delimit delimit,
+        const struct DelimitData *delimit_data)
 {
        const bool is_contig = BM_edge_is_contiguous(e);
        float angle;
@@ -92,6 +119,11 @@ static float bm_edge_calc_dissolve_error(const BMEdge *e, 
const BMO_Delimit deli
                goto fail;
        }
 
+       if ((delimit & BMO_DELIM_UV) &&
+           (bm_edge_is_contiguous_loop_cd_all(e, delimit_data) == 0)) {
+               goto fail;
+       }
+
        angle = BM_edge_calc_face_angle(e);
        if (is_contig == false) {
                angle = (float)M_PI - angle;
@@ -106,16 +138,30 @@ fail:
 
 void BM_mesh_decimate_dissolve_ex(
         BMesh *bm, const float angle_limit, const bool do_dissolve_boundaries,
-        const BMO_Delimit delimit,
+        BMO_Delimit delimit,
         BMVert **vinput_arr, const int vinput_len,
         BMEdge **einput_arr, const int einput_len,
         const short oflag_out)
 {
+       struct DelimitData delimit_data = {0};
        const int eheap_table_len = do_dissolve_boundaries ? einput_len : 
max_ii(einput_len, vinput_len);
        void *_heap_table = MEM_mallocN(sizeof(HeapNode *) * eheap_table_len, 
__func__);
 
        int i;
 
+       if (delimit & BMO_DELIM_UV) {
+               const int layer_len = CustomData_number_of_layers(&bm->ldata, 
CD_MLOOPUV);
+               if (layer_len == 0) {
+                       delimit &= ~BMO_DELIM_UV;
+               }
+               else {
+                       delimit_data.cd_loop_type = CD_MLOOPUV;
+                       delimit_data.cd_loop_size = 
CustomData_sizeof(delimit_data.cd_loop_type);
+                       delimit_data.cd_loop_offset = 
CustomData_get_n_offset(&bm->ldata, CD_MLOOPUV, 0);
+                       delimit_data.cd_loop_offset_end = 
delimit_data.cd_loop_size * layer_len;
+               }
+       }
+
        /* --- first edges --- */
        if (1) {
                BMEdge **earray;
@@ -140,7 +186,7 @@ void BM_mesh_decimate_dissolve_ex(
                /* build heap */
                for (i = 0; i < einput_len; i++) {
                        BMEdge *e = einput_arr[i];
-                       const float cost = bm_edge_calc_dissolve_error(e, 
delimit);
+                       const float cost = bm_edge_calc_dissolve_error(e, 
delimit, &delimit_data);
                        eheap_table[i] = BLI_heap_insert(eheap, cost, e);
                        BM_elem_index_set(e, i);  /* set dirty */
                }
@@ -176,7 +222,7 @@ void BM_mesh_decimate_dissolve_ex(
                                        do {
                                                const int j = 
BM_elem_index_get(l_iter->e);
                                                if (j != -1 && eheap_table[j]) {
-                                                       const float cost = 
bm_edge_calc_dissolve_error(l_iter->e, delimit);
+                                                       const float cost = 
bm_edge_calc_dissolve_error(l_iter->e, delimit, &delimit_data);
                                                        BLI_heap_remove(eheap, 
eheap_table[j]);
                                                        eheap_table[j] = 
BLI_heap_insert(eheap, cost, l_iter->e);
                                                }
diff --git a/source/blender/editors/mesh/editmesh_select.c 
b/source/blender/editors/mesh/editmesh_select.c
index bf32008..4abd0df 100644
--- a/source/blender/editors/mesh/editmesh_select.c
+++ b/source/blender/editors/mesh/editmesh_select.c
@@ -2336,6 +2336,11 @@ bool EDBM_select_interior_faces(BMEditMesh *em)
 
 /************************ Select Linked Operator *************************/
 
+struct DelimitData {
+       int cd_loop_type;
+       int cd_loop_offset;
+};
+
 static void select_linked_delimit_default(bContext *C, wmOperator *op)
 {
        PropertyRNA *prop = RNA_struct_find_property(op->ptr, "delimit");
@@ -2353,7 +2358,9 @@ static void select_linked_delimit_default(bContext *C, 
wmOperator *op)
 }
 
 
-static bool select_linked_delimit_test(BMEdge *e, int delimit)
+static bool select_linked_delimit_test(
+        BMEdge *e, int delimit,
+        const struct DelimitData *delimit_data)
 {
        BLI_assert(delimit);
 
@@ -2387,22 +2394,38 @@ static bool select_linked_delimit_test(BMEdge *e, int 
delimit)
                }
        }
 
+       if (delimit & BMO_DELIM_UV) {
+               if (BM_edge_is_contiguous_loop_cd(e, 
delimit_data->cd_loop_type, delimit_data->cd_loop_offset) == 0) {
+                       return true;
+               }
+       }
+
        return false;
 }
 
-static void select_linked_delimit_begin(BMEditMesh *em, const int delimit)
+static void select_linked_delimit_begin(BMEditMesh *em, int delimit)
 {
+       struct DelimitData delimit_data = {0};
+
        BMesh *bm = em->bm;
 
        BMIter iter;
        BMEdge *e;
 
+       if (delimit & BMO_DELIM_UV) {
+               delimit_data.cd_loop_type = CD_MLOOPUV;
+               delimit_data.cd_loop_offset = CustomData_get_offset(&bm->ldata, 
delimit_data.cd_loop_type);
+               if (delimit_data.cd_loop_offset == -1) {
+                       delimit &= ~BMO_DELIM_UV;
+               }
+       }
+
        /* grr, shouldn't need to alloc BMO flags here */
        BM_mesh_elem_toolflags_ensure(bm);
        if (em->selectmode ==  SCE_SELECT_FACE) {
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                        const bool is_walk_ok = (
-                               (select_linked_delimit_test(e, delimit) == 
false));
+                               (select_linked_delimit_test(e, delimit, 
&delimit_data) == false));
 
                        BMO_elem_flag_set(bm, e, BMO_ELE_TAG, is_walk_ok);
                }
@@ -2412,7 +2435,7 @@ static void select_linked_delimit_begin(BMEditMesh *em, 
const int delimit)
                BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
                        const bool is_walk_ok = (
                                BM_elem_flag_test(e, BM_ELEM_SELECT) ||
-                               (select_linked_delimit_test(e, delimit) == 
false));
+                               (select_linked_delimit_test(e, delimit, 
&delimit_data) == false));
 
                        BMO_elem_fl

@@ Diff output truncated at 10240 characters. @@

_______________________________________________
Bf-blender-cvs mailing list
[email protected]
http://lists.blender.org/mailman/listinfo/bf-blender-cvs

Reply via email to