[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [59125] trunk/blender/source/blender/bmesh /operators/bmo_edgenet.c: bmesh edge-net: refactor out face creation into its own function, replace array reallocation with alloca.
Campbell Barton
ideasman42 at gmail.com
Wed Aug 14 01:48:49 CEST 2013
Revision: 59125
http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=59125
Author: campbellbarton
Date: 2013-08-13 23:48:48 +0000 (Tue, 13 Aug 2013)
Log Message:
-----------
bmesh edge-net: refactor out face creation into its own function, replace array reallocation with alloca.
fix for error increasing the face tag count when the face might not be created.
Modified Paths:
--------------
trunk/blender/source/blender/bmesh/operators/bmo_edgenet.c
Modified: trunk/blender/source/blender/bmesh/operators/bmo_edgenet.c
===================================================================
--- trunk/blender/source/blender/bmesh/operators/bmo_edgenet.c 2013-08-13 23:43:44 UTC (rev 59124)
+++ trunk/blender/source/blender/bmesh/operators/bmo_edgenet.c 2013-08-13 23:48:48 UTC (rev 59125)
@@ -31,6 +31,7 @@
#include "BLI_listbase.h"
#include "BLI_math.h"
#include "BLI_array.h"
+#include "BLI_alloca.h"
#include "BLI_smallhash.h"
#include "BLI_rand.h"
#include "BLI_heap.h"
@@ -885,6 +886,67 @@
winding[(test_v1 == node->v)]++;
}
+static BMFace *bm_face_from_path(BMesh *bm, EPath *path,
+ EdgeData *edata,
+ const bool use_fill_check)
+{
+ /* accumulte winding directions for each edge which has a face */
+ const unsigned int path_len = BLI_countlist(&path->nodes);
+ unsigned int winding[2] = {0, 0};
+ unsigned int i;
+
+ EPathNode *node;
+
+ BMVert **verts = BLI_array_alloca(verts, path_len);
+ BMEdge **edges = BLI_array_alloca(edges, path_len);
+ BMEdge *e;
+ BMVert *v;
+
+ for (node = path->nodes.first, i = 0; node; node = node->next, i++) {
+
+ v = node->v;
+ e = BM_edge_exists(v, node->next ?
+ node->next->v :
+ ((EPathNode *)path->nodes.first)->v);
+
+ /* check on the winding */
+ if (e->l) {
+ if (UNLIKELY(count_edge_faces(bm, e) >= 2)) {
+ return NULL;
+ }
+
+ vote_on_winding(e, node, winding);
+ }
+
+ verts[i] = v;
+ edges[i] = e;
+ }
+
+ /* do after incase we bail early, above */
+ for (i = 0; i < path_len; i++) {
+ edata[BM_elem_index_get(edges[i])].ftag++;
+ }
+
+
+ /* if these are even it doesn't really matter what to do,
+ * with consistent geometry one will be zero, the choice is clear */
+ if (winding[0] > winding[1]) {
+ BLI_array_wrap(verts, path_len, -1);
+ BLI_array_reverse(verts, path_len);
+ BLI_array_reverse(edges, path_len);
+ }
+
+ if ((use_fill_check == false) ||
+ /* fairly expensive check - see if there are already faces filling this area */
+ (BM_face_exists_multi(verts, edges, path_len) == false))
+ {
+ return BM_face_create(bm, verts, edges, path_len, BM_CREATE_NO_DOUBLE);
+ }
+ else {
+ return NULL;
+ }
+}
+
void bmo_edgenet_fill_exec(BMesh *bm, BMOperator *op)
{
BMIter iter;
@@ -892,18 +954,14 @@
BMFace *f;
BMEdge *e;
EPath *path;
- EPathNode *node;
EdgeData *edata;
VertData *vdata;
- BMEdge **edges = NULL;
PathBase *pathbase;
- BLI_array_declare(edges);
const bool use_restrict = BMO_slot_bool_get(op->slots_in, "use_restrict");
const bool use_fill_check = BMO_slot_bool_get(op->slots_in, "use_fill_check");
const short mat_nr = BMO_slot_int_get(op->slots_in, "mat_nr");
const bool use_smooth = BMO_slot_bool_get(op->slots_in, "use_smooth");
int i;
- unsigned int winding[2]; /* accumulte winding directions for each edge which has a face */
BMOpSlot *slot_restrict = BMO_slot_get(op->slots_in, "restrict");
BMOpSlot *slot_face_groupmap_out = BMO_slot_get(op->slots_out, "face_groupmap.out");
@@ -976,78 +1034,28 @@
edata[BM_elem_index_get(edge)].tag += 1;
path = edge_find_shortest_path(bm, op, edge, edata, vdata, pathbase, group);
- if (!path)
- continue;
+ if (path && path->nodes.first) {
+ BMFace *f = bm_face_from_path(bm, path, edata,
+ use_fill_check);
- winding[0] = winding[1] = 0;
-
- BLI_array_empty(edges);
- i = 0;
- for (node = path->nodes.first; node; node = node->next) {
- e = BM_edge_exists(node->v, node->next ?
- node->next->v :
- ((EPathNode *)path->nodes.first)->v);
-
- if (count_edge_faces(bm, e) >= 2) {
- edge_free_path(pathbase, path);
- break;
+ if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
+ BMO_elem_flag_enable(bm, f, FACE_NEW);
+ f->mat_nr = mat_nr;
+ if (use_smooth) {
+ BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
+ }
}
- /* check on the winding */
- if (e->l) {
- vote_on_winding(e, node, winding);
+ if (use_restrict) {
+ BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
}
- edata[BM_elem_index_get(e)].ftag++;
- BLI_array_grow_one(edges);
- edges[i++] = e;
+ edge_free_path(pathbase, path);
}
-
- /* above loop quit early */
- if (node) {
- continue;
- }
-
- if (i) {
- BMVert *v1, *v2;
-
- /* if these are even it doesn't really matter what to do,
- * with consistent geometry one will be zero, the choice is clear */
- node = path->nodes.first;
- if (winding[0] < winding[1]) {
- v1 = node->v;
- v2 = node->next->v;
- }
- else {
- v1 = node->next->v;
- v2 = node->v;
- }
-
- if ((use_fill_check == false) ||
- /* fairly expensive check - see if there are already faces filling this area */
- (BM_face_exists_multi_edge(edges, i) == false))
- {
- f = BM_face_create_ngon(bm, v1, v2, edges, i, BM_CREATE_NO_DOUBLE);
- if (f && !BMO_elem_flag_test(bm, f, ELE_ORIG)) {
- BMO_elem_flag_enable(bm, f, FACE_NEW);
- f->mat_nr = mat_nr;
- if (use_smooth) {
- BM_elem_flag_enable(f, BM_ELEM_SMOOTH);
- }
- }
-
- if (use_restrict) {
- BMO_slot_map_int_insert(op, slot_face_groupmap_out, f, path->group);
- }
- }
- }
-
- edge_free_path(pathbase, path);
}
BMO_slot_buffer_from_enabled_flag(bm, op, op->slots_out, "faces.out", BM_FACE, FACE_NEW);
- BLI_array_free(edges);
edge_pathbase_free(pathbase);
MEM_freeN(edata);
MEM_freeN(vdata);
More information about the Bf-blender-cvs
mailing list