Blender  V2.93
bmesh_edgesplit.c
Go to the documentation of this file.
1 /*
2  * This program is free software; you can redistribute it and/or
3  * modify it under the terms of the GNU General Public License
4  * as published by the Free Software Foundation; either version 2
5  * of the License, or (at your option) any later version.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * along with this program; if not, write to the Free Software Foundation,
14  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
15  */
16 
23 #include "MEM_guardedalloc.h"
24 
25 #include "BLI_utildefines.h"
26 
27 #include "bmesh.h"
28 
29 #include "bmesh_edgesplit.h" /* own include */
30 
37  const bool use_verts,
38  const bool tag_only,
39  const bool copy_select)
40 {
41  BMIter iter;
42  BMEdge *e;
43 
44  bool use_ese = false;
45  GHash *ese_gh = NULL;
46 
47  if (copy_select && bm->selected.first) {
48  BMEditSelection *ese;
49 
50  ese_gh = BLI_ghash_ptr_new(__func__);
51  for (ese = bm->selected.first; ese; ese = ese->next) {
52  if (ese->htype != BM_FACE) {
53  BLI_ghash_insert(ese_gh, ese->ele, ese);
54  }
55  }
56 
57  use_ese = true;
58  }
59 
60  if (tag_only == false) {
61  BM_mesh_elem_hflag_enable_all(bm, BM_EDGE | (use_verts ? BM_VERT : 0), BM_ELEM_TAG, false);
62  }
63 
64  if (use_verts) {
65  /* prevent one edge having both verts unflagged
66  * we could alternately disable these edges, either way its a corner case.
67  *
68  * This is needed so we don't split off the edge but then none of its verts which
69  * would leave a duplicate edge.
70  */
71  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
73  if (UNLIKELY(((BM_elem_flag_test(e->v1, BM_ELEM_TAG) == false) &&
74  (BM_elem_flag_test(e->v2, BM_ELEM_TAG) == false)))) {
77  }
78  }
79  }
80  }
81  else {
82  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
86  }
87  }
88  }
89 
90  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
92  uint i;
93  for (i = 0; i < 2; i++) {
94  BMVert *v = ((&e->v1)[i]);
97 
98  if (use_ese) {
99  BMVert **vtar;
100  int vtar_len;
101 
102  BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, &vtar, &vtar_len);
103 
104  /* first value is always in 'v' */
105  if (vtar_len > 1) {
106  BMEditSelection *ese = BLI_ghash_lookup(ese_gh, v);
107  BLI_assert(v == vtar[0]);
108  if (UNLIKELY(ese)) {
109  int j;
110  for (j = 1; j < vtar_len; j++) {
111  BLI_assert(v != vtar[j]);
113  }
114  }
115  }
116  MEM_freeN(vtar);
117  }
118  else {
119  BM_vert_separate_hflag(bm, v, BM_ELEM_TAG, copy_select, NULL, NULL);
120  }
121  }
122  }
123  }
124  }
125 
126 #ifndef NDEBUG
127  /* ensure we don't have any double edges! */
128  BM_ITER_MESH (e, &iter, bm, BM_EDGES_OF_MESH) {
131  }
132  }
133 #endif
134 
135  if (use_ese) {
136  BLI_ghash_free(ese_gh, NULL, NULL);
137  }
138 }
#define BLI_assert(a)
Definition: BLI_assert.h:58
void BLI_ghash_insert(GHash *gh, void *key, void *val)
Definition: BLI_ghash.c:756
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new(const char *info) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void * BLI_ghash_lookup(GHash *gh, const void *key) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:803
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNLIKELY(x)
Read Guarded memory(de)allocation.
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_vert_separate_hflag(BMesh *bm, BMVert *v, const char hflag, const bool copy_select, BMVert ***r_vout, int *r_vout_len)
Definition: bmesh_core.c:2522
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)
Definition: bmesh_inline.h:29
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_elem_flag_enable(ele, hflag)
Definition: bmesh_inline.h:28
#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)
BMEdge * BM_edge_find_double(BMEdge *e)
Definition: bmesh_query.c:2028
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
struct BMEditSelection * next
Definition: bmesh_marking.h:24
ListBase selected
Definition: bmesh_class.h:356
void * first
Definition: DNA_listBase.h:47