Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCampbell Barton <ideasman42@gmail.com>2015-12-13 16:15:36 +0300
committerCampbell Barton <ideasman42@gmail.com>2015-12-13 16:16:09 +0300
commita158a74700afb06564a8293cc96b98ead62b9fa9 (patch)
tree332b90f4b3bb4a3df25bd86ad4f10659e17debea /source/blender/editors/mesh/editmesh_intersect.c
parentb7090b3d1c0fdeee9d6b2d136db6c9b8ff6ad48c (diff)
BMesh: split-face by edges support isolated edges
Previously edges needed to be connected to the faces.
Diffstat (limited to 'source/blender/editors/mesh/editmesh_intersect.c')
-rw-r--r--source/blender/editors/mesh/editmesh_intersect.c142
1 files changed, 141 insertions, 1 deletions
diff --git a/source/blender/editors/mesh/editmesh_intersect.c b/source/blender/editors/mesh/editmesh_intersect.c
index 4fa97506d2b..ea166f4e9c2 100644
--- a/source/blender/editors/mesh/editmesh_intersect.c
+++ b/source/blender/editors/mesh/editmesh_intersect.c
@@ -27,10 +27,13 @@
#include "DNA_object_types.h"
#include "BLI_math.h"
+#include "BLI_memarena.h"
+#include "BLI_stack.h"
#include "BLI_buffer.h"
+#include "BLI_kdopbvh.h"
#include "BLI_linklist_stack.h"
-
+#include "BKE_editmesh_bvh.h"
#include "BKE_context.h"
#include "BKE_report.h"
#include "BKE_editmesh.h"
@@ -49,6 +52,10 @@
#include "tools/bmesh_intersect.h"
+
+/* detect isolated holes and fill them */
+#define USE_NET_ISLAND_CONNECT
+
/**
* Compare selected with its self.
*/
@@ -366,6 +373,72 @@ static void bm_face_split_by_edges(
}
}
+#ifdef USE_NET_ISLAND_CONNECT
+
+struct LinkBase {
+ LinkNode *list;
+ unsigned int list_len;
+};
+
+static void ghash_insert_face_edge_link(
+ GHash *gh, BMFace *f_key, BMEdge *e_val,
+ MemArena *mem_arena)
+{
+ void **ls_base_p;
+ struct LinkBase *ls_base;
+ LinkNode *ls;
+
+ if (!BLI_ghash_ensure_p(gh, f_key, &ls_base_p)) {
+ ls_base = *ls_base_p = BLI_memarena_alloc(mem_arena, sizeof(*ls_base));
+ ls_base->list = NULL;
+ ls_base->list_len = 0;
+ }
+ else {
+ ls_base = *ls_base_p;
+ }
+
+ ls = BLI_memarena_alloc(mem_arena, sizeof(*ls));
+ ls->next = ls_base->list;
+ ls->link = e_val;
+ ls_base->list = ls;
+ ls_base->list_len += 1;
+}
+
+static void bm_face_split_by_edges_island_connect(
+ BMesh *bm, BMFace *f,
+ LinkNode *e_link, const int e_link_len,
+ MemArena *mem_arena_edgenet)
+{
+ BMEdge **edge_arr = BLI_memarena_alloc(mem_arena_edgenet, sizeof(BMEdge **) * e_link_len);
+ int edge_arr_len = 0;
+
+ while (e_link) {
+ edge_arr[edge_arr_len++] = e_link->link;
+ e_link = e_link->next;
+ }
+
+ {
+ unsigned int edge_arr_holes_len;
+ BMEdge **edge_arr_holes;
+ if (BM_face_split_edgenet_connect_islands(
+ bm, f,
+ edge_arr, e_link_len,
+ mem_arena_edgenet,
+ &edge_arr_holes, &edge_arr_holes_len))
+ {
+ edge_arr_len = edge_arr_holes_len;
+ edge_arr = edge_arr_holes; /* owned by the arena */
+ }
+ }
+
+ BM_face_split_edgenet(
+ bm, f, edge_arr, edge_arr_len,
+ NULL, NULL);
+}
+
+#endif /* USE_NET_ISLAND_CONNECT */
+
+
static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
{
Object *obedit = CTX_data_edit_object(C);
@@ -485,9 +558,76 @@ static int edbm_face_split_by_edges_exec(bContext *C, wmOperator *UNUSED(op))
BLI_buffer_free(&edge_net_temp_buf);
}
+#ifdef USE_NET_ISLAND_CONNECT
+ /* before overwriting edge index values, collect edges left untouched */
+ BLI_Stack *edges_loose = BLI_stack_new(sizeof(BMEdge * ), __func__);
+ BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
+ if (BM_elem_index_get(e) == -1 && BM_edge_is_wire(e)) {
+ BLI_stack_push(edges_loose, &e);
+ }
+ }
+#endif
+
EDBM_mesh_normals_update(em);
EDBM_update_generic(em, true, true);
+
+#ifdef USE_NET_ISLAND_CONNECT
+ /* we may have remaining isolated regions remaining,
+ * these will need to have connecting edges created */
+ if (!BLI_stack_is_empty(edges_loose)) {
+ GHash *face_edge_map = BLI_ghash_ptr_new(__func__);
+
+ MemArena *mem_arena = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ {
+ BMBVHTree *bmbvh = BKE_bmbvh_new(bm, em->looptris, em->tottri, BMBVH_RESPECT_SELECT, NULL, NULL);
+
+ while (!BLI_stack_is_empty(edges_loose)) {
+ BLI_stack_pop(edges_loose, &e);
+ float e_center[3];
+ mid_v3_v3v3(e_center, e->v1->co, e->v2->co);
+
+ f = BKE_bmbvh_find_face_closest(bmbvh, e_center, FLT_MAX);
+ if (f) {
+ ghash_insert_face_edge_link(face_edge_map, f, e, mem_arena);
+ }
+ }
+
+ BKE_bmbvh_free(bmbvh);
+ }
+
+ {
+ MemArena *mem_arena_edgenet = BLI_memarena_new(BLI_MEMARENA_STD_BUFSIZE, __func__);
+
+ GHashIterator gh_iter;
+
+ GHASH_ITER(gh_iter, face_edge_map) {
+ f = BLI_ghashIterator_getKey(&gh_iter);
+ struct LinkBase *e_ls_base = BLI_ghashIterator_getValue(&gh_iter);
+
+ bm_face_split_by_edges_island_connect(
+ bm, f,
+ e_ls_base->list, e_ls_base->list_len,
+ mem_arena_edgenet);
+
+ BLI_memarena_clear(mem_arena_edgenet);
+ }
+
+ BLI_memarena_free(mem_arena_edgenet);
+ }
+
+ BLI_memarena_free(mem_arena);
+
+ BLI_ghash_free(face_edge_map, NULL, NULL);
+
+ EDBM_mesh_normals_update(em);
+ EDBM_update_generic(em, true, true);
+ }
+
+ BLI_stack_free(edges_loose);
+#endif /* USE_NET_ISLAND_CONNECT */
+
return OPERATOR_FINISHED;
}