Commit: 9ce20d3341cf215233f46f0326a9619fe80b6cb2
Author: Campbell Barton
Date:   Tue May 26 13:39:07 2015 +1000
Branches: master
https://developer.blender.org/rB9ce20d3341cf215233f46f0326a9619fe80b6cb2

BMesh: join tris now delimits all UV/Color layers

Previously was only checking active layers

Also add delimit by edge seam

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

M       source/blender/bmesh/intern/bmesh_opdefines.c
M       source/blender/bmesh/operators/bmo_join_triangles.c
M       source/blender/editors/mesh/editmesh_tools.c

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

diff --git a/source/blender/bmesh/intern/bmesh_opdefines.c 
b/source/blender/bmesh/intern/bmesh_opdefines.c
index 2ba65f5..211c53a 100644
--- a/source/blender/bmesh/intern/bmesh_opdefines.c
+++ b/source/blender/bmesh/intern/bmesh_opdefines.c
@@ -493,6 +493,7 @@ static BMOpDefine bmo_join_triangles_def = {
        "join_triangles",
        /* slots_in */
        {{"faces", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},    /* input geometry. */
+        {"cmp_seam", BMO_OP_SLOT_BOOL},
         {"cmp_sharp", BMO_OP_SLOT_BOOL},
         {"cmp_uvs", BMO_OP_SLOT_BOOL},
         {"cmp_vcols", BMO_OP_SLOT_BOOL},
diff --git a/source/blender/bmesh/operators/bmo_join_triangles.c 
b/source/blender/bmesh/operators/bmo_join_triangles.c
index 5705b8e..06200ba 100644
--- a/source/blender/bmesh/operators/bmo_join_triangles.c
+++ b/source/blender/bmesh/operators/bmo_join_triangles.c
@@ -42,164 +42,219 @@
 
 #include "intern/bmesh_operators_private.h" /* own include */
 
-#define FACE_OUT (1 << 0)
-
 /* assumes edges are validated before reaching this poin */
-static float measure_facepair(
+static float quad_calc_error(
         const float v1[3], const float v2[3],
-        const float v3[3], const float v4[3],
-        const float limit)
+        const float v3[3], const float v4[3])
 {
        /* gives a 'weight' to a pair of triangles that join an edge to decide 
how good a join they would make */
        /* Note: this is more complicated than it needs to be and should be 
cleaned up.. */
-       float n1[3], n2[3], measure = 0.0f, angle1, angle2, diff;
-       float edgeVec1[3], edgeVec2[3], edgeVec3[3], edgeVec4[3];
-       float minarea, maxarea, areaA, areaB;
-
-       /* First Test: Normal difference */
-       normal_tri_v3(n1, v1, v2, v3);
-       normal_tri_v3(n2, v1, v3, v4);
-       angle1 = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : 
angle_normalized_v3v3(n1, n2);
-
-       normal_tri_v3(n1, v2, v3, v4);
-       normal_tri_v3(n2, v4, v1, v2);
-       angle2 = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : 
angle_normalized_v3v3(n1, n2);
-
-       measure += (angle1 + angle2) * 0.5f;
-       if (measure > limit) {
-               return measure;
-       }
+       float error = 0.0f;
+
+       /* Normal difference */
+       {
+               float n1[3], n2[3];
+               float angle_a, angle_b;
+               float diff;
 
-       /* Second test: Colinearity */
-       sub_v3_v3v3(edgeVec1, v1, v2);
-       sub_v3_v3v3(edgeVec2, v2, v3);
-       sub_v3_v3v3(edgeVec3, v3, v4);
-       sub_v3_v3v3(edgeVec4, v4, v1);
-
-       normalize_v3(edgeVec1);
-       normalize_v3(edgeVec2);
-       normalize_v3(edgeVec3);
-       normalize_v3(edgeVec4);
-
-       /* a completely skinny face is 'pi' after halving */
-       diff = 0.25f * (fabsf(angle_normalized_v3v3(edgeVec1, edgeVec2) - 
(float)M_PI_2) +
-                       fabsf(angle_normalized_v3v3(edgeVec2, edgeVec3) - 
(float)M_PI_2) +
-                       fabsf(angle_normalized_v3v3(edgeVec3, edgeVec4) - 
(float)M_PI_2) +
-                       fabsf(angle_normalized_v3v3(edgeVec4, edgeVec1) - 
(float)M_PI_2));
-
-       if (!diff) {
-               return 0.0;
+               normal_tri_v3(n1, v1, v2, v3);
+               normal_tri_v3(n2, v1, v3, v4);
+               angle_a = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : 
angle_normalized_v3v3(n1, n2);
+
+               normal_tri_v3(n1, v2, v3, v4);
+               normal_tri_v3(n2, v4, v1, v2);
+               angle_b = (compare_v3v3(n1, n2, FLT_EPSILON)) ? 0.0f : 
angle_normalized_v3v3(n1, n2);
+
+               diff = (angle_a + angle_b) / (float)(M_PI * 2);
+
+               error += diff;
        }
 
-       measure +=  diff;
-       if (measure > limit) {
-               return measure;
+       /* Colinearity */
+       {
+               float edge_vecs[4][3];
+               float diff;
+
+               sub_v3_v3v3(edge_vecs[0], v1, v2);
+               sub_v3_v3v3(edge_vecs[1], v2, v3);
+               sub_v3_v3v3(edge_vecs[2], v3, v4);
+               sub_v3_v3v3(edge_vecs[3], v4, v1);
+
+               normalize_v3(edge_vecs[0]);
+               normalize_v3(edge_vecs[1]);
+               normalize_v3(edge_vecs[2]);
+               normalize_v3(edge_vecs[3]);
+
+               /* a completely skinny face is 'pi' after halving */
+               diff = (fabsf(angle_normalized_v3v3(edge_vecs[0], edge_vecs[1]) 
- (float)M_PI_2) +
+                       fabsf(angle_normalized_v3v3(edge_vecs[1], edge_vecs[2]) 
- (float)M_PI_2) +
+                       fabsf(angle_normalized_v3v3(edge_vecs[2], edge_vecs[3]) 
- (float)M_PI_2) +
+                       fabsf(angle_normalized_v3v3(edge_vecs[3], edge_vecs[0]) 
- (float)M_PI_2)) / (float)(M_PI * 2);
+
+               error += diff;
        }
 
-       /* Third test: Concavity */
-       areaA = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v3, v4);
-       areaB = area_tri_v3(v2, v3, v4) + area_tri_v3(v4, v1, v2);
+       /* Concavity */
+       {
+               float area_min, area_max, area_a, area_b;
+               float diff;
 
-       if (areaA <= areaB) minarea = areaA;
-       else minarea = areaB;
+               area_a = area_tri_v3(v1, v2, v3) + area_tri_v3(v1, v3, v4);
+               area_b = area_tri_v3(v2, v3, v4) + area_tri_v3(v4, v1, v2);
 
-       if (areaA >= areaB) maxarea = areaA;
-       else maxarea = areaB;
+               area_min = min_ff(area_a, area_b);
+               area_max = max_ff(area_a, area_b);
 
-       if (!maxarea) measure += 1;
-       else measure += (1 - (minarea / maxarea));
+               diff = area_max ? (1.0 - (area_min / area_max)) : 1.0f;
 
-       return measure;
+               error += diff;
+       }
+
+       return error;
 }
 
-#define T2QUV_LIMIT 0.005f
-#define T2QCOL_LIMIT 3
+static void bm_edge_to_quad_verts(const BMEdge *e, const BMVert *r_v_quad[4])
+{
+       BLI_assert(e->l->f->len == 3 && e->l->radial_next->f->len == 3);
+       BLI_assert(BM_edge_is_manifold(e));
+       r_v_quad[0] = e->l->v;
+       r_v_quad[1] = e->l->prev->v;
+       r_v_quad[2] = e->l->next->v;
+       r_v_quad[3] = e->l->radial_next->prev->v;
+}
 
-static bool bm_edge_faces_cmp(BMesh *bm, BMEdge *e, const bool do_uv, const 
bool do_tf, const bool do_vcol)
+/* cache customdata delimiters */
+struct DelimitData_CD {
+       int cd_type;
+       int cd_size;
+       int cd_offset;
+       int cd_offset_end;
+};
+
+struct DelimitData {
+       unsigned int do_seam : 1;
+       unsigned int do_sharp : 1;
+       unsigned int do_mat : 1;
+       unsigned int do_angle : 1;
+
+       float angle;
+       float angle__cos;
+
+       struct DelimitData_CD cdata[4];
+       int cdata_len;
+};
+
+static bool bm_edge_is_contiguous_loop_cd_all(
+        const BMEdge *e, const struct DelimitData_CD *delimit_data)
 {
-       /* first get loops */
-       BMLoop *l[4];
-
-       l[0] = e->l;
-       l[2] = e->l->radial_next;
-       
-       /* match up loops on each side of an edge corresponding to each vert */
-       if (l[0]->v == l[2]->v) {
-               l[1] = l[0]->next;
-               l[3] = l[1]->next;
+       int cd_offset;
+       for (cd_offset = delimit_data->cd_offset;
+            cd_offset < delimit_data->cd_offset_end;
+            cd_offset += delimit_data->cd_size)
+       {
+               if (BM_edge_is_contiguous_loop_cd(e, delimit_data->cd_type, 
cd_offset) == false) {
+                       return false;
+               }
        }
-       else {
-               l[1] = l[0]->next;
 
-               l[3] = l[2];
-               l[2] = l[3]->next;
+       return true;
+}
+
+static bool bm_edge_delimit_cdata(
+        CustomData *ldata, CustomDataType type,
+        struct DelimitData_CD *r_delim_cd)
+{
+       const int layer_len = CustomData_number_of_layers(ldata, type);
+       r_delim_cd->cd_type = type;
+       r_delim_cd->cd_size = CustomData_sizeof(r_delim_cd->cd_type);
+       r_delim_cd->cd_offset = CustomData_get_n_offset(ldata, type, 0);
+       r_delim_cd->cd_offset_end = r_delim_cd->cd_size * layer_len;
+       return (r_delim_cd->cd_offset != -1);
+}
+
+static float bm_edge_is_delimit(
+        const BMEdge *e,
+        const struct DelimitData *delimit_data)
+{
+       BMFace *f_a = e->l->f, *f_b = e->l->radial_next->f;
+#if 0
+       const bool is_contig = BM_edge_is_contiguous(e);
+       float angle;
+#endif
+
+       if ((delimit_data->do_seam) &&
+           (BM_elem_flag_test(e, BM_ELEM_SEAM)))
+       {
+               goto fail;
        }
 
-       /* Test UV's */
-       if (do_uv) {
-               const MLoopUV *luv[4] = {
-                   CustomData_bmesh_get(&bm->ldata, l[0]->head.data, 
CD_MLOOPUV),
-                   CustomData_bmesh_get(&bm->ldata, l[1]->head.data, 
CD_MLOOPUV),
-                   CustomData_bmesh_get(&bm->ldata, l[2]->head.data, 
CD_MLOOPUV),
-                   CustomData_bmesh_get(&bm->ldata, l[3]->head.data, 
CD_MLOOPUV),
-               };
-
-               /* do UV */
-               if (luv[0] && (!compare_v2v2(luv[0]->uv, luv[2]->uv, 
T2QUV_LIMIT) ||
-                              !compare_v2v2(luv[1]->uv, luv[3]->uv, 
T2QUV_LIMIT)))
-               {
-                       return false;
-               }
+       if ((delimit_data->do_sharp) &&
+           (BM_elem_flag_test(e, BM_ELEM_SMOOTH) == 0))
+       {
+               goto fail;
        }
 
-       if (do_tf) {
-               const MTexPoly *tp[2] = {
-                   CustomData_bmesh_get(&bm->pdata, l[0]->f->head.data, 
CD_MTEXPOLY),
-                   CustomData_bmesh_get(&bm->pdata, l[1]->f->head.data, 
CD_MTEXPOLY),
-               };
+       if ((delimit_data->do_mat) &&
+           (f_a->mat_nr != f_b->mat_nr))
+       {
+               goto fail;
+       }
 
-               if (tp[0] && (tp[0]->tpage != tp[1]->tpage)) {
-                       return false;
+       if (delimit_data->do_angle) {
+               if (dot_v3v3(f_a->no, f_b->no) < delimit_data->angle__cos) {
+                       goto fail;
+               }
+               else {
+                       const BMVert *verts[4];
+                       float edge_vecs[4][3];
+
+                       bm_edge_to_quad_verts(e, verts);
+
+                       sub_v3_v3v3(edge_vecs[0], verts[0]->co, verts[1]->co);
+                       sub_v3_v3v3(edge_vecs[1], verts[1]->co, verts[2]->co);
+                       sub_v3_v3v3(edge_vecs[2], verts[2]->co, verts[3]->co);
+                       sub_v3_v3v3(edge_vecs[3], verts[3]->co, verts[0]->co);
+
+                       normalize_v3(edge_vecs[0]);
+                       normalize_v3(edge_vecs[1]);
+                       normalize_v3(edge_vecs[2]);
+                       normalize_v3(edge_vecs[3]);
+
+                       if ((fabsf(angle_normalized_v3v3(edge_vecs[0], 
edge_vecs[1]) - (float)M_PI_2) > delimit_data->angle) ||
+                           (fabsf(angle_normalized_v3v3(edge_vecs[1], 
edge_vecs[2]) - (float)M_PI_2) > delimit_data->angle) ||
+                           (fabsf(angle_normalized_v3v3(edge_vecs[2], 
edge_vecs[3]) - (float)M_PI_2) > delimit_data->angle) ||
+                           (fabsf(angle_normalized_v3v3(edge_vecs[3], 
edge_vecs[0]) - (float)M_PI_2) > delimit_data->angle))
+                       {
+                               goto fail;
+                       }
                }
        }
 
-       /* Test Vertex Colors */
-       if (do_vcol) {
-               const MLoopCol *lcol[4] = {
-                   CustomData_bmesh_get(&bm->ldata, l[0]->head.data, 
CD_MLOOPCOL),
-                       CustomData_bmesh_get(&bm->ldata, l[1]->head.data, 
CD_MLOOPCOL),
-                       CustomData_bmesh_get(&bm->ldata, l[2]->head.data, 
CD_MLOOPCOL),
-                       CustomData_bmesh_get(&bm->ldata, l[3]->head.data, 
CD_MLOOPCOL),
-               };
-
-               if (lcol[0]) {
-                       if (!compare_rgb_uchar((unsigned char *)&lcol[0]->r, 
(unsigned char *)&lcol[2]->r, T2QCOL_LIMIT) ||
-                           !compare_rgb_uchar((unsigned char *)&lcol[1]->r, 
(unsigned char *)&lcol[3]->r, T2QCOL_LIMIT))
-                       {
-                               return false;
+       if (delimit_data->cdata_len) {
+               int i;
+               for (i = 0; i < delimit_data->cdata_len; i++) {
+                       if (!bm_edge_is_contiguous_loop_cd_all(e, 
&delimit_data->cdata[i])) {
+                               goto fail;
                        }
                }
        }
 
+       return false;
+
+fail:
        return true;
 }
 
 
-#define EDGE_MARK      1
-#define EDGE_CHOSEN    2
-
-#define FACE_MARK      1
-#defin

@@ 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