[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [56831] trunk/blender: bmesh, grid fill tool.
Campbell Barton
ideasman42 at gmail.com
Wed May 15 22:34:41 CEST 2013
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. @@
More information about the Bf-blender-cvs
mailing list