Blender V4.3
bmesh_edgesplit.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11#include "MEM_guardedalloc.h"
12
13#include "BLI_listbase.h"
14#include "BLI_utildefines.h"
15
16#include "bmesh.hh"
17
18#include "bmesh_edgesplit.hh" /* own include */
19
21 const bool use_verts,
22 const bool tag_only,
23 const bool copy_select)
24{
25 BMIter iter;
26 BMEdge *e;
27
28 bool use_ese = false;
29 GHash *ese_gh = nullptr;
30
31 if (copy_select && bm->selected.first) {
32 ese_gh = BLI_ghash_ptr_new(__func__);
34 if (ese->htype != BM_FACE) {
35 BLI_ghash_insert(ese_gh, ese->ele, ese);
36 }
37 }
38
39 use_ese = true;
40 }
41
42 if (tag_only == false) {
43 BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false);
44 }
45
46 if (use_verts) {
47 /* prevent one edge having both verts unflagged
48 * we could alternately disable these edges, either way its a corner case.
49 *
50 * This is needed so we don't split off the edge but then none of its verts which
51 * would leave a duplicate edge.
52 */
55 if (UNLIKELY((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) &&
56 (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false)))
57 {
60 }
61 }
62 }
63 }
64 else {
69 }
70 }
71 }
72
75 uint i;
76 for (i = 0; i < 2; i++) {
77 BMVert *v = ((&e->v1)[i]);
80
81 if (use_ese) {
82 BMVert **vtar;
83 int vtar_len;
84
85 BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, &vtar, &vtar_len);
86
87 /* first value is always in 'v' */
88 if (vtar_len > 1) {
89 BMEditSelection *ese = static_cast<BMEditSelection *>(BLI_ghash_lookup(ese_gh, v));
90 BLI_assert(v == vtar[0]);
91 if (UNLIKELY(ese)) {
92 int j;
93 for (j = 1; j < vtar_len; j++) {
94 BLI_assert(v != vtar[j]);
96 }
97 }
98 }
99 MEM_freeN(vtar);
100 }
101 else {
102 BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, nullptr, nullptr);
103 }
104 }
105 }
106 }
107 }
108
109#ifndef NDEBUG
110 /* ensure we don't have any double edges! */
111 BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
113 BLI_assert(BM_edge_find_double(e) == nullptr);
114 }
115 }
116#endif
117
118 if (use_ese) {
119 BLI_ghash_free(ese_gh, nullptr, nullptr);
120 }
121}
#define BLI_assert(a)
Definition BLI_assert.h:50
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(const GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:731
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition BLI_ghash.c:707
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:860
#define LISTBASE_FOREACH(type, var, list)
unsigned int uint
#define UNLIKELY(x)
Read Guarded memory(de)allocation.
@ BM_ELEM_TAG
void BM_vert_separate_hflag(BMesh *bm, BMVert *v, const char hflag, const bool copy_select, BMVert ***r_vout, int *r_vout_len)
void BM_mesh_edgesplit(BMesh *bm, const bool use_verts, const bool tag_only, const bool copy_select)
#define BM_elem_flag_disable(ele, hflag)
#define BM_elem_flag_test(ele, hflag)
#define BM_elem_flag_enable(ele, hflag)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_EDGES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_enable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
#define BM_select_history_store_after_notest(bm, ese_ref, ele)
#define BM_FACE
#define BM_EDGE
#define BM_VERT
BMEdge * BM_edge_find_double(BMEdge *e)
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
ListBase selected
void * first