[Bf-committers] [Bf-blender-cvs] SVN commit: /data/svn/bf-blender [55585] trunk/blender/source/blender/bmesh /operators/bmo_beautify.c: improve beauty-fill tool for non-flat triangles.

Jonathan Williamson jonathan at cgcookie.com
Tue Mar 26 02:51:58 CET 2013


Nice one! Thanks Campbell, huge improvement.

On Monday, March 25, 2013, Campbell Barton wrote:

> Revision: 55585
>
> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=55585
> Author:   campbellbarton
> Date:     2013-03-26 01:49:55 +0000 (Tue, 26 Mar 2013)
> Log Message:
> -----------
> improve beauty-fill tool for non-flat triangles.
> Project the triangle pair into 2d coords before measuring.
>
> before/after -
> http://www.graphicall.org/ftp/ideasman42/beauty_fill_fix.png
>
> note: I committed this r54403 but it caused eternal looping so I reverted
> for 2.66 release.
> ran extensive tests and its not giving problems so re-applying this
> improvement.
>
> Revision Links:
> --------------
>
> http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=54403
>
> Modified Paths:
> --------------
>     trunk/blender/source/blender/bmesh/operators/bmo_beautify.c
>
> Modified: trunk/blender/source/blender/bmesh/operators/bmo_beautify.c
> ===================================================================
> --- trunk/blender/source/blender/bmesh/operators/bmo_beautify.c 2013-03-26
> 01:46:12 UTC (rev 55584)
> +++ trunk/blender/source/blender/bmesh/operators/bmo_beautify.c 2013-03-26
> 01:49:55 UTC (rev 55585)
> @@ -86,6 +86,9 @@
>  static void erot_state_ex(const BMEdge *e, int v_index[2], int f_index[2])
>  {
>         BLI_assert(BM_edge_is_manifold((BMEdge *)e));
> +       BLI_assert(BM_vert_in_edge(e, e->l->prev->v)              ==
> false);
> +       BLI_assert(BM_vert_in_edge(e, e->l->radial_next->prev->v) ==
> false);
> +
>         /* verts of the edge */
>         v_index[0] = BM_elem_index_get(e->v1);
>         v_index[1] = BM_elem_index_get(e->v2);
> @@ -151,10 +154,11 @@
>                 is_breaked = true;
>
>                 for (i = 0; i < edge_array_len; i++) {
> -                       BMVert *v1, *v2, *v3, *v4;
>                         BMEdge *e = edge_array[i];
>                         GHash *e_state_hash;
>
> +                       float v1_xy[2], v2_xy[2], v3_xy[2], v4_xy[2];
> +
>                         BLI_assert(BM_edge_is_manifold(e) == true);
>                         BLI_assert(BMO_elem_flag_test(bm, e->l->f,
> FACE_MARK) &&
>                                    BMO_elem_flag_test(bm,
> e->l->radial_next->f, FACE_MARK));
> @@ -178,62 +182,106 @@
>                                 }
>                         }
>
> -                       v1 = e->l->prev->v;               /* first face
> vert not attached to 'e' */
> -                       v2 = e->l->v;                     /* e->v1 or
> e->v2*/
> -                       v3 = e->l->radial_next->prev->v;  /* second face
> vert not attached to 'e' */
> -                       v4 = e->l->next->v;               /* e->v1 or
> e->v2*/
> +                       {
> +                               const float *v1, *v2, *v3, *v4;
> +                               bool is_zero_a, is_zero_b;
> +                               float no[3];
> +                               float axis_mat[3][3];
>
> -                       if (UNLIKELY(v1 == v3)) {
> -                               // printf("This should never happen, but
> does sometimes!\n");
> -                               continue;
> +                               v1 = e->l->prev->v->co;               /*
> first face co */
> +                               v2 = e->l->v->co;                     /*
> e->v1 or e->v2*/
> +                               v3 = e->l->radial_next->prev->v->co;  /*
> second face co */
> +                               v4 = e->l->next->v->co;               /*
> e->v1 or e->v2*/
> +
> +                               if (UNLIKELY(v1 == v3)) {
> +                                       // printf("This should never
> happen, but does sometimes!\n");
> +                                       continue;
> +                               }
> +
> +                               // printf("%p %p %p %p - %p %p\n", v1, v2,
> v3, v4, e->l->f, e->l->radial_next->f);
> +                               BLI_assert((ELEM3(v1, v2, v3, v4) ==
> false) &&
> +                                          (ELEM3(v2, v1, v3, v4) ==
> false) &&
> +                                          (ELEM3(v3, v1, v2, v4) ==
> false) &&
> +                                          (ELEM3(v4, v1, v2, v3) ==
> false));
> +
> +                               is_zero_a = area_tri_v3(v2, v3, v4) <=
> FLT_EPSILON;
> +                               is_zero_b = area_tri_v3(v2, v4, v1) <=
> FLT_EPSILON;
> +
> +                               if (LIKELY(is_zero_a == false && is_zero_b
> == false)) {
> +                                       float no_a[3], no_b[3];
> +                                       normal_tri_v3(no_a, v2, v3, v4);
>  /* a */
> +                                       normal_tri_v3(no_b, v2, v4, v1);
>  /* b */
> +                                       add_v3_v3v3(no, no_a, no_b);
> +                                       if (UNLIKELY(normalize_v3(no) <=
> FLT_EPSILON)) {
> +                                               continue;
> +                                       }
> +                               }
> +                               else if (is_zero_a == false) {
> +                                       normal_tri_v3(no, v2, v3, v4);  /*
> a */
> +                               }
> +                               else if (is_zero_b == false) {
> +                                       normal_tri_v3(no, v2, v4, v1);  /*
> b */
> +                               }
> +                               else {
> +                                       /* both zero area, no useful
> normal can be calculated */
> +                                       continue;
> +                               }
> +
> +                               // { float a = angle_normalized_v3v3(no_a,
> no_b); printf("~ %.7f\n", a); fflush(stdout);}
> +
> +                               axis_dominant_v3_to_m3(axis_mat, no);
> +                               mul_v2_m3v3(v1_xy, axis_mat, v1);
> +                               mul_v2_m3v3(v2_xy, axis_mat, v2);
> +                               mul_v2_m3v3(v3_xy, axis_mat, v3);
> +                               mul_v2_m3v3(v4_xy, axis_mat, v4);
>                         }
>
>                         // printf("%p %p %p %p - %p %p\n", v1, v2, v3, v4,
> e->l->f, e->l->radial_next->f);
> -                       BLI_assert((ELEM3(v1, v2, v3, v4) == false) &&
> -                                  (ELEM3(v2, v1, v3, v4) == false) &&
> -                                  (ELEM3(v3, v1, v2, v4) == false) &&
> -                                  (ELEM3(v4, v1, v2, v3) == false));
>
> -                       if (is_quad_convex_v3(v1->co, v2->co, v3->co,
> v4->co)) {
> +                       if (is_quad_convex_v2(v1_xy, v2_xy, v3_xy, v4_xy))
> {
>                                 float len1, len2, len3, len4, len5, len6,
> opp1, opp2, fac1, fac2;
>                                 /* testing rule:
>                                  * the area divided by the total edge
> lengths
>                                  */
> -                               len1 = len_v3v3(v1->co, v2->co);
> -                               len2 = len_v3v3(v2->co, v3->co);
> -                               len3 = len_v3v3(v3->co, v4->co);
> -                               len4 = len_v3v3(v4->co, v1->co);
> -                               len5 = len_v3v3(v1->co, v3->co);
> -                               len6 = len_v3v3(v2->co, v4->co);
> +                               len1 = len_v2v2(v1_xy, v2_xy);
> +                               len2 = len_v2v2(v2_xy, v3_xy);
> +                               len3 = len_v2v2(v3_xy, v4_xy);
> +                               len4 = len_v2v2(v4_xy, v1_xy);
> +                               len5 = len_v2v2(v1_xy, v3_xy);
> +                               len6 = len_v2v2(v2_xy, v4_xy);
>
> -                               opp1 = area_tri_v3(v1->co, v2->co, v3->co);
> -                               opp2 = area_tri_v3(v1->co, v3->co, v4->co);
> +                               opp1 = area_tri_v2(v1_xy, v2_xy, v3_xy);
> +                               opp2 = area_tri_v2(v1_xy, v3_xy, v4_xy);
>
>                                 fac1 = opp1 / (len1 + len2 + len5) + opp2
> / (len3 + len4 + len5);
>
> -                               opp1 = area_tri_v3(v2->co, v3->co, v4->co);
> -                               opp2 = area_tri_v3(v2->co, v4->co, v1->co);
> +                               opp1 = area_tri_v2(v2_xy, v3_xy, v4_xy);
> +                               opp2 = area_tri_v2(v2_xy, v4_xy, v1_xy);
>
>                                 fac2 = opp1 / (len2 + len3 + len6) + opp2
> / (len4 + len1 + len6);
>
>                                 if (fac1 > fac2) {
> -
> -                                       EdRotState *e_state =
> BLI_mempool_alloc(edge_state_pool);
> -                                       erot_state_current(e, e_state);
> -
>                                         e = BM_edge_rotate(bm, e, false,
> BM_EDGEROT_CHECK_EXISTS);
>                                         if (LIKELY(e)) {
> -                                               /* maintain the index
> array */
> -                                               edge_array[i] = e;
> -                                               BM_elem_index_set(e, i);
>
> -
> -                                               /* add this state into the
> hash */
> +                                               /* add the new state into
> the hash so we don't move into this state again
> +                                                * note: we could add the
> previous state too but this isn't essential)
> +                                                *       for avoiding
> eternal loops */
> +                                               EdRotState *e_state =
> BLI_mempool_all



-- 
Jonathan Williamson
http://cgcookie.com


More information about the Bf-committers mailing list