[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [58606] trunk/blender: mesh tool to fill in holes, added in mesh clean menu,

Campbell Barton ideasman42 at gmail.com
Thu Jul 25 20:43:06 CEST 2013


Revision: 58606
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=58606
Author:   campbellbarton
Date:     2013-07-25 18:43:05 +0000 (Thu, 25 Jul 2013)
Log Message:
-----------
mesh tool to fill in holes, added in mesh clean menu,
unlike other face creation tools it copies data from surrounding faces.

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_construct.c
    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_fill_holes.c

Modified: trunk/blender/release/scripts/startup/bl_ui/space_view3d.py
===================================================================
--- trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/release/scripts/startup/bl_ui/space_view3d.py	2013-07-25 18:43:05 UTC (rev 58606)
@@ -1822,6 +1822,7 @@
         layout.menu("VIEW3D_MT_edit_mesh_edges")
         layout.menu("VIEW3D_MT_edit_mesh_faces")
         layout.menu("VIEW3D_MT_edit_mesh_normals")
+        layout.menu("VIEW3D_MT_edit_mesh_clean")
 
         layout.separator()
 
@@ -2084,6 +2085,15 @@
         layout.operator("mesh.flip_normals")
 
 
+class VIEW3D_MT_edit_mesh_clean(Menu):
+    bl_label = "Clean"
+
+    def draw(self, context):
+        layout = self.layout
+
+        layout.operator("mesh.fill_holes")
+
+
 class VIEW3D_MT_edit_mesh_delete(Menu):
     bl_label = "Delete"
 

Modified: trunk/blender/source/blender/bmesh/CMakeLists.txt
===================================================================
--- trunk/blender/source/blender/bmesh/CMakeLists.txt	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/bmesh/CMakeLists.txt	2013-07-25 18:43:05 UTC (rev 58606)
@@ -51,6 +51,7 @@
 	operators/bmo_extrude.c
 	operators/bmo_fill_edgeloop.c
 	operators/bmo_fill_grid.c
+	operators/bmo_fill_holes.c
 	operators/bmo_hull.c
 	operators/bmo_inset.c
 	operators/bmo_join_triangles.c

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_construct.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_construct.c	2013-07-25 18:43:05 UTC (rev 58606)
@@ -324,6 +324,7 @@
 	BMEdge **edge_arr = BLI_array_alloca(edge_arr, len);
 	unsigned int winding[2] = {0, 0};
 	int i, i_prev = len - 1;
+	BMVert *v_winding[2] = {vert_arr[i_prev], vert_arr[0]};
 
 	BLI_assert(len > 2);
 
@@ -375,8 +376,8 @@
 	/* create the face */
 	return BM_face_create_ngon(
 	        bm,
-	        vert_arr[(len - 2) + winding[0]],
-	        vert_arr[(len - 1) + winding[1]],
+	        v_winding[winding[0]],
+	        v_winding[winding[1]],
 	        edge_arr, len, create_flag);
 }
 

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_opdefines.c	2013-07-25 18:43:05 UTC (rev 58606)
@@ -552,7 +552,30 @@
 	BMO_OPTYPE_FLAG_NORMALS_CALC | BMO_OPTYPE_FLAG_SELECT_FLUSH,
 };
 
+
 /*
+ * Fill Holes.
+ *
+ * Fill boundary edges with faces, copying surrounding customdata.
+ */
+static BMOpDefine bmo_holes_fill_def = {
+	"holes_fill",
+	/* slots_in */
+	{{"edges", BMO_OP_SLOT_ELEMENT_BUF, {BM_EDGE}}, /* input edges */
+	 {"sides",          BMO_OP_SLOT_INT},   /* number of face sides to fill */
+	 {{'\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_holes_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.
@@ -1724,6 +1747,7 @@
 	&bmo_dissolve_limit_def,
 	&bmo_dissolve_verts_def,
 	&bmo_duplicate_def,
+	&bmo_holes_fill_def,
 	&bmo_edgeloop_fill_def,
 	&bmo_edgenet_fill_def,
 	&bmo_edgenet_prepare_def,

Modified: trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h
===================================================================
--- trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/bmesh/intern/bmesh_operators_private.h	2013-07-25 18:43:05 UTC (rev 58606)
@@ -58,6 +58,7 @@
 void bmo_dissolve_verts_exec(BMesh *bm, BMOperator *op);
 void bmo_duplicate_exec(BMesh *bm, BMOperator *op);
 void bmo_edgeloop_fill_exec(BMesh *bm, BMOperator *op);
+void bmo_holes_fill_exec(BMesh *bm, BMOperator *op);
 void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op);
 void bmo_edgenet_prepare_exec(BMesh *bm, BMOperator *op);
 void bmo_extrude_discrete_faces_exec(BMesh *bm, BMOperator *op);

Added: trunk/blender/source/blender/bmesh/operators/bmo_fill_holes.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_fill_holes.c	                        (rev 0)
+++ trunk/blender/source/blender/bmesh/operators/bmo_fill_holes.c	2013-07-25 18:43:05 UTC (rev 58606)
@@ -0,0 +1,137 @@
+/*
+ * ***** 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_fill_holes.c
+ *  \ingroup bmesh
+ *
+ * Fill boundary edge loop(s) with faces.
+ */
+
+#include "MEM_guardedalloc.h"
+
+#include "BLI_listbase.h"
+#include "BLI_array.h"
+#include "BLI_math.h"
+
+#include "bmesh.h"
+
+#include "intern/bmesh_operators_private.h" /* own include */
+
+#define EDGE_MARK	2
+#define ELE_OUT		4
+
+/**
+ * Clone of BM_face_find_longest_loop that ensures the loop has an adjacent face
+ */
+static BMLoop *bm_face_find_longest_loop_manifold(BMFace *f)
+{
+	BMLoop *longest_loop = NULL;
+	float longest_len = 0.0f;
+	BMLoop *l_iter, *l_first;
+
+	l_iter = l_first = BM_FACE_FIRST_LOOP(f);
+
+	do {
+		if (BM_edge_is_boundary(l_iter->e) == false) {
+			const float len = len_squared_v3v3(l_iter->v->co, l_iter->next->v->co);
+			if (len >= longest_len) {
+				longest_loop = l_iter;
+				longest_len = len;
+			}
+		}
+	} while ((l_iter = l_iter->next) != l_first);
+
+	return longest_loop;
+}
+
+static BMFace *bm_face_from_eloop(BMesh *bm, struct BMEdgeLoopStore *el_store)
+{
+	LinkData *node = BM_edgeloop_verts_get(el_store)->first;
+	const int len = BM_edgeloop_length_get(el_store);
+	BMVert **f_verts = BLI_array_alloca(f_verts, len);
+	BMFace *f;
+	BMLoop *l;
+	unsigned int i = 0;
+
+	do {
+		f_verts[i++] = node->data;
+	} while ((node = node->next));
+
+	f = BM_face_create_ngon_verts(bm, f_verts, len, 0, true, false);
+	BM_face_copy_shared(bm, f);
+
+	l = bm_face_find_longest_loop_manifold(f);
+	if (l) {
+		BMFace *f_other = l->radial_next->f;
+		BLI_assert(l->radial_next != l);
+		BM_elem_attrs_copy(bm, bm, f_other, f);
+	}
+
+	return f;
+}
+
+static bool bm_edge_test_cb(BMEdge *e, void *bm_v)
+{
+	return BMO_elem_flag_test((BMesh *)bm_v, e, EDGE_MARK);
+}
+
+void bmo_holes_fill_exec(BMesh *bm, BMOperator *op)
+{
+	ListBase eloops = {NULL, NULL};
+	LinkData *el_store;
+
+	BMEdge *e;
+	int count;
+
+	BMOIter siter;
+
+	const int  sides    = BMO_slot_int_get(op->slots_in,  "sides");
+
+	/* clear tags */
+
+	BM_mesh_elem_hflag_disable_all(bm, BM_FACE, BM_ELEM_TAG, false);
+
+	/* tag edges that may be apart of loops */
+	BMO_ITER (e, &siter, op->slots_in, "edges", BM_EDGE) {
+		BMO_elem_flag_set(bm, e, EDGE_MARK, BM_edge_is_boundary(e));
+	}
+
+	count = BM_mesh_edgeloops_find(bm, &eloops, bm_edge_test_cb, (void *)bm);
+
+	for (el_store = eloops.first; el_store; el_store = el_store->next) {
+		if (BM_edgeloop_is_closed((struct BMEdgeLoopStore *)el_store)) {
+			const int len = BM_edgeloop_length_get((struct BMEdgeLoopStore *)el_store);
+			if ((sides == 0) || (len <= sides)) {
+				BMFace *f;
+
+				f = bm_face_from_eloop(bm, (struct BMEdgeLoopStore *)el_store);
+				BMO_elem_flag_enable(bm, f, ELE_OUT);
+			}
+		}
+	}
+
+	(void)count;
+
+	BM_mesh_edgeloops_free(&eloops);
+
+	BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, ELE_OUT);
+}


Property changes on: trunk/blender/source/blender/bmesh/operators/bmo_fill_holes.c
___________________________________________________________________
Added: svn:eol-style
   + native

Modified: trunk/blender/source/blender/editors/mesh/editmesh_tools.c
===================================================================
--- trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/editors/mesh/editmesh_tools.c	2013-07-25 18:43:05 UTC (rev 58606)
@@ -2752,8 +2752,44 @@
 	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
 }
 
+static int edbm_fill_holes_exec(bContext *C, wmOperator *op)
+{
+	Object *obedit = CTX_data_edit_object(C);
+	BMEditMesh *em = BKE_editmesh_from_object(obedit);
+	const int sides = RNA_int_get(op->ptr, "sides");
 
+	if (!EDBM_op_call_and_selectf(
+	        em, op,
+	        "faces.out", true,
+	        "holes_fill edges=%he sides=%i",
+	        BM_ELEM_SELECT, sides))
+	{
+		return OPERATOR_CANCELLED;
+	}
 
+	EDBM_update_generic(em, true, true);
+
+	return OPERATOR_FINISHED;
+
+}
+
+void MESH_OT_fill_holes(wmOperatorType *ot)
+{
+	/* identifiers */
+	ot->name = "Fill Holes";
+	ot->idname = "MESH_OT_fill_holes";
+	ot->description = "Fill in holes (boundary edge loops)";
+
+	/* api callbacks */
+	ot->exec = edbm_fill_holes_exec;
+	ot->poll = ED_operator_editmesh;
+
+	/* flags */
+	ot->flag = OPTYPE_REGISTER | OPTYPE_UNDO;
+
+	RNA_def_int(ot->srna, "sides", 4, 0, INT_MAX, "Sides", "Number of sides (zero disables)", 0, 100);
+}
+
 static int edbm_beautify_fill_exec(bContext *C, wmOperator *op)
 {
 	Object *obedit = CTX_data_edit_object(C);

Modified: trunk/blender/source/blender/editors/mesh/mesh_intern.h
===================================================================
--- trunk/blender/source/blender/editors/mesh/mesh_intern.h	2013-07-25 18:16:55 UTC (rev 58605)
+++ trunk/blender/source/blender/editors/mesh/mesh_intern.h	2013-07-25 18:43:05 UTC (rev 58606)
@@ -196,6 +196,7 @@
 void MESH_OT_separate(struct wmOperatorType *ot);

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list