Revision: 56831
          
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=56831
Author:   campbellbarton
Date:     2013-05-15 20:34:40 +0000 (Wed, 15 May 2013)
Log Message:
-----------
bmesh, grid fill tool.

This uses 2 edge loops and fills them with a grid, taking into account 
curvature of surrounding edges.
Access from face menu: Ctrl+F,G

http://www.graphicall.org/ftp/ideasman42/grid_fill.png

Modified Paths:
--------------
    trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
    trunk/blender/source/blender/bmesh/CMakeLists.txt
    trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
    trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h
    trunk/blender/source/blender/editors/mesh/editmesh_tools.c
    trunk/blender/source/blender/editors/mesh/mesh_intern.h
    trunk/blender/source/blender/editors/mesh/mesh_ops.c

Added Paths:
-----------
    trunk/blender/source/blender/bmesh/operators/bmo_grid_fill.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py 2013-05-15 
19:24:07 UTC (rev 56830)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py 2013-05-15 
20:34:40 UTC (rev 56831)
@@ -1966,6 +1966,7 @@
         layout.operator("mesh.flip_normals")
         layout.operator("mesh.edge_face_add")
         layout.operator("mesh.fill")
+        layout.operator("mesh.fill_grid")
         layout.operator("mesh.beautify_fill")
         layout.operator("mesh.inset")
         layout.operator("mesh.bevel").vertex_only = False

Modified: trunk/blender/source/blender/bmesh/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/bmesh/CMakeLists.txt   2013-05-15 19:24:07 UTC 
(rev 56830)
+++ trunk/blender/source/blender/bmesh/CMakeLists.txt   2013-05-15 20:34:40 UTC 
(rev 56831)
@@ -50,6 +50,7 @@
        operators/bmo_edgenet.c
        operators/bmo_edgesplit.c
        operators/bmo_extrude.c
+       operators/bmo_grid_fill.c
        operators/bmo_hull.c
        operators/bmo_inset.c
        operators/bmo_join_triangles.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2013-05-15 
19:24:07 UTC (rev 56830)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c 2013-05-15 
20:34:40 UTC (rev 56831)
@@ -530,6 +530,29 @@
 };
 
 /*
+ * Grid Fill.
+ *
+ * Create faces defined by 2 disconnected edge loops (which share edges).
+ */
+static BMOpDefine bmo_grid_fill_def = {
+       "grid_fill",
+       /* slots_in */
+       {{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+       /* restricts edges to groups.  maps edges to integer */
+        {"mat_nr",         BMO_OP_SLOT_INT},      /* material to use */
+        {"use_smooth",     BMO_OP_SLOT_BOOL},     /* smooth state to use */
+        {{'\0'}},
+       },
+       /* slots_out */
+       /* maps new faces to the group numbers they came from */
+       {{"faces.out", BMO_OP_SLOT_ELEMENT_BUF, {BM_FACE}},     /* new faces */
+        {{'\0'}},
+       },
+       bmo_grid_fill_exec,
+       BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
+};
+
+/*
  * Edge Loop Fill.
  *
  * Create faces defined by one or more non overlapping edge loops.
@@ -1701,6 +1724,7 @@
        &bmo_extrude_face_region_def,
        &bmo_extrude_vert_indiv_def,
        &bmo_find_doubles_def,
+       &bmo_grid_fill_def,
        &bmo_inset_individual_def,
        &bmo_inset_region_def,
        &bmo_join_triangles_def,

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h 
2013-05-15 19:24:07 UTC (rev 56830)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h 
2013-05-15 20:34:40 UTC (rev 56831)
@@ -65,6 +65,7 @@
 void bmo_extrude_face_region_exec(BMesh *bm, BMOperator *op);
 void bmo_extrude_vert_indiv_exec(BMesh *bm, BMOperator *op);
 void bmo_find_doubles_exec(BMesh *bm, BMOperator *op);
+void bmo_grid_fill_exec(BMesh *bm, BMOperator *op);
 void bmo_inset_individual_exec(BMesh *bm, BMOperator *op);
 void bmo_inset_region_exec(BMesh *bm, BMOperator *op);
 void bmo_join_triangles_exec(BMesh *bm, BMOperator *op);

Added: trunk/blender/source/blender/bmesh/operators/bmo_grid_fill.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_grid_fill.c                
                (rev 0)
+++ trunk/blender/source/blender/bmesh/operators/bmo_grid_fill.c        
2013-05-15 20:34:40 UTC (rev 56831)
@@ -0,0 +1,418 @@
+/*
+ * ***** BEGIN GPL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+ *
+ * Contributor(s): Campbell Barton.
+ *
+ * ***** END GPL LICENSE BLOCK *****
+ */
+
+/** \file blender/bmesh/operators/bmo_grid_fill.c
+ *  \ingroup bmesh
+ *
+ * Fill 2 isolated, open edge loops with a grid of quads.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_math.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define EDGE_MARK      4
+#define FACE_OUT       16
+
+#define BARYCENTRIC_INTERP
+
+#ifdef BARYCENTRIC_INTERP
+/**
+ * 2 edge vectors to normal.
+ */
+static void quad_edges_to_normal(
+        float no[3],
+        const float co_a1[3], const float co_a2[3],
+        const float co_b1[3], const float co_b2[3])
+{
+       float diff_a[3];
+       float diff_b[3];
+
+       sub_v3_v3v3(diff_a, co_a2, co_a1);
+       sub_v3_v3v3(diff_b, co_b2, co_b1);
+       normalize_v3(diff_a);
+       normalize_v3(diff_b);
+       add_v3_v3v3(no, diff_a, diff_b);
+       normalize_v3(no);
+}
+
+static void quad_verts_to_barycentric_tri(
+        float tri[3][3],
+        float co_a[3],
+        float co_b[3],
+
+        float co_a_next[3],
+        float co_b_next[3],
+
+        float co_a_prev[3],
+        float co_b_prev[3],
+        bool is_flip
+        )
+{
+       float no[3];
+
+       copy_v3_v3(tri[0], co_a);
+       copy_v3_v3(tri[1], co_b);
+
+       quad_edges_to_normal(no,
+                            co_a, co_a_next,
+                            co_b, co_b_next);
+
+       if (co_a_prev) {
+               float no_t[3];
+               quad_edges_to_normal(no_t,
+                                    co_a_prev, co_a,
+                                    co_b_prev, co_b);
+               add_v3_v3(no, no_t);
+               normalize_v3(no);
+       }
+
+       if (is_flip) negate_v3(no);
+       mul_v3_fl(no, len_v3v3(tri[0], tri[1]));
+
+       mid_v3_v3v3(tri[2], tri[0], tri[1]);
+       add_v3_v3(tri[2], no);
+}
+
+#endif
+
+
+/**
+ * This may be useful outside the bmesh operator.
+ *
+ * \param v_grid  2d array of verts, all boundary verts must be set, we fill 
in the middle.
+ */
+static void bm_grid_fill_array(BMesh *bm, BMVert **v_grid, const int xtot, 
const int ytot,
+                               const short mat_nr, const bool use_smooth,
+                               const bool use_flip)
+{
+       int x, y;
+
+#define XY(_x, _y)  ((_x) + ((_y) * (xtot)))
+
+#ifdef BARYCENTRIC_INTERP
+       float tri_a[3][3];
+       float tri_b[3][3];
+       float tri_t[3][3];  /* temp */
+
+       quad_verts_to_barycentric_tri(
+               tri_a,
+               v_grid[XY(0,        0)]->co,
+               v_grid[XY(xtot - 1, 0)]->co,
+               v_grid[XY(0,        1)]->co,
+               v_grid[XY(xtot - 1, 1)]->co,
+               NULL, NULL,
+               false);
+
+       quad_verts_to_barycentric_tri(
+               tri_b,
+               v_grid[XY(0,        (ytot - 1))]->co,
+               v_grid[XY(xtot - 1, (ytot - 1))]->co,
+               v_grid[XY(0,        (ytot - 2))]->co,
+               v_grid[XY(xtot - 1, (ytot - 2))]->co,
+               NULL, NULL,
+               true);
+#endif
+
+       /* Build Verts */
+       for (y = 1; y < ytot - 1; y++) {
+#ifdef BARYCENTRIC_INTERP
+               quad_verts_to_barycentric_tri(
+                       tri_t,
+                       v_grid[XY(0,        y + 0)]->co,
+                       v_grid[XY(xtot - 1, y + 0)]->co,
+                       v_grid[XY(0,        y + 1)]->co,
+                       v_grid[XY(xtot - 1, y + 1)]->co,
+                       v_grid[XY(0,        y - 1)]->co,
+                       v_grid[XY(xtot - 1, y - 1)]->co,
+                       false);
+#endif
+               for (x = 1; x < xtot - 1; x++) {
+                       float co[3];
+                       BMVert *v;
+                       /* we may want to allow sparse filled arrays, but for 
now, ensure its empty */
+                       BLI_assert(v_grid[(y * xtot) + x] == NULL);
+
+                       /* place the vertex */
+#ifdef BARYCENTRIC_INTERP
+                       {
+                               float co_a[3], co_b[3];
+
+                               barycentric_transform(
+                                           co_a,
+                                           v_grid[x]->co,
+                                           tri_t[0], tri_t[1], tri_t[2],
+                                           tri_a[0], tri_a[1], tri_a[2]);
+                               barycentric_transform(
+                                           co_b,
+                                           v_grid[(xtot * ytot) + (x - 
xtot)]->co,
+                                           tri_t[0], tri_t[1], tri_t[2],
+                                           tri_b[0], tri_b[1], tri_b[2]);
+
+                               interp_v3_v3v3(co, co_a, co_b, (float)y / 
((float)ytot - 1));
+                       }
+
+#else
+                       interp_v3_v3v3(
+                               co,
+                               v_grid[x]->co,
+                               v_grid[(xtot * ytot) + (x - xtot)]->co,
+                               (float)y / ((float)ytot - 1));
+#endif
+
+                       v = BM_vert_create(bm, co, NULL, 0);
+                       v_grid[(y * xtot) + x] = v;
+               }
+       }
+
+       /* Build Faces */
+       for (x = 0; x < xtot - 1; x++) {
+               for (y = 0; y < ytot - 1; y++) {
+                       BMFace *f;
+
+                       if (use_flip) {
+                               f = BM_face_create_quad_tri(
+                                       bm,
+                                       v_grid[XY(x,     y + 0)],  /* BL */
+                                       v_grid[XY(x,     y + 1)],  /* TL */
+                                       v_grid[XY(x + 1, y + 1)],  /* TR */
+                                       v_grid[XY(x + 1, y + 0)],  /* BR */
+                                       NULL,
+                                       false);
+                       }
+                       else {
+                               f = BM_face_create_quad_tri(
+                                       bm,
+                                       v_grid[XY(x + 1, y + 0)],  /* BR */
+                                       v_grid[XY(x + 1, y + 1)],  /* TR */
+                                       v_grid[XY(x,     y + 1)],  /* TL */
+                                       v_grid[XY(x,     y + 0)],  /* BL */
+                                       NULL,
+                                       false);
+                       }
+                       BMO_elem_flag_enable(bm, f, FACE_OUT);
+                       f->mat_nr = mat_nr;
+                       if (use_smooth) {
+                               BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+                       }
+               }
+       }
+#undef XY
+}
+
+static void bm_grid_fill(BMesh *bm,
+                         struct BMEdgeLoopStore *estore_a,      struct 
BMEdgeLoopStore *estore_b,
+                         struct BMEdgeLoopStore *estore_rail_a, struct 
BMEdgeLoopStore *estore_rail_b,
+                         const short mat_nr, const bool use_smooth)
+{
+#define USE_FLIP_DETECT
+
+       const int xtot = BM_edgeloop_length_get(estore_a);
+       const int ytot = BM_edgeloop_length_get(estore_rail_a);
+       //BMVert *v;
+       int i;
+       int x, y;
+       LinkData *el;
+       bool use_flip = false;
+
+       ListBase *lb_a = BM_edgeloop_verts_get(estore_a);
+       ListBase *lb_b = BM_edgeloop_verts_get(estore_b);
+
+       ListBase *lb_rail_a = BM_edgeloop_verts_get(estore_rail_a);
+       ListBase *lb_rail_b = BM_edgeloop_verts_get(estore_rail_b);
+
+       BMVert **v_grid = MEM_callocN(sizeof(BMVert *) * xtot * ytot, __func__);
+       /**
+        * <pre>
+        *           estore_b
+        *          +------------------+

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