[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