Blender  V3.3
bmesh_iterators.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
11 #include "MEM_guardedalloc.h"
12 
13 #include "BLI_bitmap.h"
14 #include "BLI_utildefines.h"
15 
16 #include "bmesh.h"
17 #include "intern/bmesh_private.h"
18 
20  '\0',
21  BM_VERT, /* BM_VERTS_OF_MESH */
22  BM_EDGE, /* BM_EDGES_OF_MESH */
23  BM_FACE, /* BM_FACES_OF_MESH */
24  BM_EDGE, /* BM_EDGES_OF_VERT */
25  BM_FACE, /* BM_FACES_OF_VERT */
26  BM_LOOP, /* BM_LOOPS_OF_VERT */
27  BM_VERT, /* BM_VERTS_OF_EDGE */
28  BM_FACE, /* BM_FACES_OF_EDGE */
29  BM_VERT, /* BM_VERTS_OF_FACE */
30  BM_EDGE, /* BM_EDGES_OF_FACE */
31  BM_LOOP, /* BM_LOOPS_OF_FACE */
32  BM_LOOP, /* BM_LOOPS_OF_LOOP */
33  BM_LOOP, /* BM_LOOPS_OF_EDGE */
34 };
35 
36 int BM_iter_mesh_count(const char itype, BMesh *bm)
37 {
38  int count;
39 
40  switch (itype) {
41  case BM_VERTS_OF_MESH:
42  count = bm->totvert;
43  break;
44  case BM_EDGES_OF_MESH:
45  count = bm->totedge;
46  break;
47  case BM_FACES_OF_MESH:
48  count = bm->totface;
49  break;
50  default:
51  count = 0;
52  BLI_assert(0);
53  break;
54  }
55 
56  return count;
57 }
58 
59 void *BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
60 {
61  BMIter iter;
62  void *val;
63  int i;
64 
65  /* sanity check */
66  if (index < 0) {
67  return NULL;
68  }
69 
70  val = BM_iter_new(&iter, bm, itype, data);
71 
72  i = 0;
73  while (i < index) {
74  val = BM_iter_step(&iter);
75  i++;
76  }
77 
78  return val;
79 }
80 
81 int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len)
82 {
83  int i = 0;
84 
85  /* sanity check */
86  if (len > 0) {
87  BMIter iter;
88  void *ele;
89 
90  for (ele = BM_iter_new(&iter, bm, itype, data); ele; ele = BM_iter_step(&iter)) {
91  array[i] = ele;
92  i++;
93  if (i == len) {
94  return len;
95  }
96  }
97  }
98 
99  return i;
100 }
102  const char *slot_name,
103  const char restrictmask,
104  void **array,
105  const int len)
106 {
107  int i = 0;
108 
109  /* sanity check */
110  if (len > 0) {
111  BMOIter oiter;
112  void *ele;
113 
114  for (ele = BMO_iter_new(&oiter, slot_args, slot_name, restrictmask); ele;
115  ele = BMO_iter_step(&oiter)) {
116  array[i] = ele;
117  i++;
118  if (i == len) {
119  return len;
120  }
121  }
122  }
123 
124  return i;
125 }
126 
128  const char itype,
129  void *data,
130  int *r_len,
131  /* optional args to avoid an alloc (normally stack array) */
132  void **stack_array,
133  int stack_array_size)
134 {
135  BMIter iter;
136 
137  BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
138 
139  /* We can't rely on #BMIter.count being set. */
140  switch (itype) {
141  case BM_VERTS_OF_MESH:
142  iter.count = bm->totvert;
143  break;
144  case BM_EDGES_OF_MESH:
145  iter.count = bm->totedge;
146  break;
147  case BM_FACES_OF_MESH:
148  iter.count = bm->totface;
149  break;
150  default:
151  break;
152  }
153 
154  if (BM_iter_init(&iter, bm, itype, data) && iter.count > 0) {
155  BMElem *ele;
156  BMElem **array = iter.count > stack_array_size ?
157  MEM_mallocN(sizeof(ele) * iter.count, __func__) :
158  stack_array;
159  int i = 0;
160 
161  *r_len = iter.count; /* set before iterating */
162 
163  while ((ele = BM_iter_step(&iter))) {
164  array[i++] = ele;
165  }
166  return array;
167  }
168 
169  *r_len = 0;
170  return NULL;
171 }
172 
174  const char *slot_name,
175  const char restrictmask,
176  int *r_len,
177  /* optional args to avoid an alloc (normally stack array) */
178  void **stack_array,
179  int stack_array_size)
180 {
181  BMOIter iter;
182  BMElem *ele;
183  const int slot_len = BMO_slot_buffer_len(slot_args, slot_name);
184 
185  BLI_assert(stack_array_size == 0 || (stack_array_size && stack_array));
186 
187  if ((ele = BMO_iter_new(&iter, slot_args, slot_name, restrictmask)) && slot_len > 0) {
188  BMElem **array = slot_len > stack_array_size ? MEM_mallocN(sizeof(ele) * slot_len, __func__) :
189  stack_array;
190  int i = 0;
191 
192  do {
193  array[i++] = ele;
194  } while ((ele = BMO_iter_step(&iter)));
195  BLI_assert(i <= slot_len);
196 
197  if (i != slot_len) {
198  if ((void **)array != stack_array) {
199  array = MEM_reallocN(array, sizeof(ele) * i);
200  }
201  }
202  *r_len = i;
203  return array;
204  }
205 
206  *r_len = 0;
207  return NULL;
208 }
209 
211  BMesh *bm,
212  BLI_bitmap *bitmap,
213  bool (*test_fn)(BMElem *, void *user_data),
214  void *user_data)
215 {
216  BMIter iter;
217  BMElem *ele;
218  int i;
219  int bitmap_enabled = 0;
220 
221  BM_ITER_MESH_INDEX (ele, &iter, bm, itype, i) {
222  if (test_fn(ele, user_data)) {
223  BLI_BITMAP_ENABLE(bitmap, i);
224  bitmap_enabled++;
225  }
226  else {
227  BLI_BITMAP_DISABLE(bitmap, i);
228  }
229  }
230 
231  return bitmap_enabled;
232 }
233 
235  BLI_bitmap *bitmap,
236  bool (*test_fn)(BMFace *, void *user_data),
237  void *user_data)
238 {
239  BMIter iter;
240  BMFace *f;
241  int i;
242  int j = 0;
243  int bitmap_enabled = 0;
244 
245  BM_ITER_MESH_INDEX (f, &iter, bm, BM_FACES_OF_MESH, i) {
246  if (test_fn(f, user_data)) {
247  for (int tri = 2; tri < f->len; tri++) {
248  BLI_BITMAP_ENABLE(bitmap, j);
249  bitmap_enabled++;
250  j++;
251  }
252  }
253  else {
254  for (int tri = 2; tri < f->len; tri++) {
255  BLI_BITMAP_DISABLE(bitmap, j);
256  j++;
257  }
258  }
259  }
260 
261  return bitmap_enabled;
262 }
263 
264 int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value)
265 {
266  BMIter iter;
267  BMElem *ele;
268  int count = 0;
269 
270  BM_ITER_ELEM (ele, &iter, data, itype) {
271  if (BM_elem_flag_test_bool(ele, hflag) == value) {
272  count++;
273  }
274  }
275 
276  return count;
277 }
278 
280  BMesh *bm, const char itype, void *data, const short oflag, const bool value)
281 {
282  BMIter iter;
283  int count = 0;
284 
285  /* loops have no header flags */
287 
288  switch (bm_iter_itype_htype_map[itype]) {
289  case BM_VERT: {
290  BMVert *ele;
291  BM_ITER_ELEM (ele, &iter, data, itype) {
292  if (BMO_vert_flag_test_bool(bm, ele, oflag) == value) {
293  count++;
294  }
295  }
296  break;
297  }
298  case BM_EDGE: {
299  BMEdge *ele;
300  BM_ITER_ELEM (ele, &iter, data, itype) {
301  if (BMO_edge_flag_test_bool(bm, ele, oflag) == value) {
302  count++;
303  }
304  }
305  break;
306  }
307  case BM_FACE: {
308  BMFace *ele;
309  BM_ITER_ELEM (ele, &iter, data, itype) {
310  if (BMO_face_flag_test_bool(bm, ele, oflag) == value) {
311  count++;
312  }
313  }
314  break;
315  }
316  }
317  return count;
318 }
319 
320 int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value)
321 {
322  BMIter iter;
323  BMElem *ele;
324  int count = 0;
325 
326  BM_ITER_MESH (ele, &iter, bm, itype) {
327  if (BM_elem_flag_test_bool(ele, hflag) == value) {
328  count++;
329  }
330  }
331 
332  return count;
333 }
334 
349 /*
350  * VERT OF MESH CALLBACKS
351  */
352 
353 /* see bug T36923 for why we need this,
354  * allow adding but not removing, this isn't _totally_ safe since
355  * you could add/remove within the same loop, but catches common cases
356  */
357 #ifdef DEBUG
358 # define USE_IMMUTABLE_ASSERT
359 #endif
360 
362 {
363 #ifdef USE_IMMUTABLE_ASSERT
364  ((BMIter *)iter)->count = BLI_mempool_len(iter->pooliter.pool);
365 #endif
366  BLI_mempool_iternew(iter->pooliter.pool, &iter->pooliter);
367 }
368 
370 {
371 #ifdef USE_IMMUTABLE_ASSERT
372  BLI_assert(((BMIter *)iter)->count <= BLI_mempool_len(iter->pooliter.pool));
373 #endif
374  return BLI_mempool_iterstep(&iter->pooliter);
375 }
376 
377 #ifdef USE_IMMUTABLE_ASSERT
378 # undef USE_IMMUTABLE_ASSERT
379 #endif
380 
381 /*
382  * EDGE OF VERT CALLBACKS
383  */
384 
386 {
387  if (iter->vdata->e) {
388  iter->e_first = iter->vdata->e;
389  iter->e_next = iter->vdata->e;
390  }
391  else {
392  iter->e_first = NULL;
393  iter->e_next = NULL;
394  }
395 }
396 
398 {
399  BMEdge *e_curr = iter->e_next;
400 
401  if (iter->e_next) {
402  iter->e_next = bmesh_disk_edge_next(iter->e_next, iter->vdata);
403  if (iter->e_next == iter->e_first) {
404  iter->e_next = NULL;
405  }
406  }
407 
408  return e_curr;
409 }
410 
411 /*
412  * FACE OF VERT CALLBACKS
413  */
414 
416 {
417  ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
418  if (((BMIter *)iter)->count) {
419  iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
420  iter->e_first = iter->l_first->e;
421  iter->e_next = iter->e_first;
422  iter->l_next = iter->l_first;
423  }
424  else {
425  iter->l_first = iter->l_next = NULL;
426  iter->e_first = iter->e_next = NULL;
427  }
428 }
430 {
431  BMLoop *l_curr = iter->l_next;
432 
433  if (((BMIter *)iter)->count && iter->l_next) {
434  ((BMIter *)iter)->count--;
435  iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
436  if (iter->l_next == iter->l_first) {
437  iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
438  iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
439  iter->l_next = iter->l_first;
440  }
441  }
442 
443  if (!((BMIter *)iter)->count) {
444  iter->l_next = NULL;
445  }
446 
447  return l_curr ? l_curr->f : NULL;
448 }
449 
450 /*
451  * LOOP OF VERT CALLBACKS
452  */
453 
455 {
456  ((BMIter *)iter)->count = bmesh_disk_facevert_count(iter->vdata);
457  if (((BMIter *)iter)->count) {
458  iter->l_first = bmesh_disk_faceloop_find_first(iter->vdata->e, iter->vdata);
459  iter->e_first = iter->l_first->e;
460  iter->e_next = iter->e_first;
461  iter->l_next = iter->l_first;
462  }
463  else {
464  iter->l_first = iter->l_next = NULL;
465  iter->e_first = iter->e_next = NULL;
466  }
467 }
469 {
470  BMLoop *l_curr = iter->l_next;
471 
472  if (((BMIter *)iter)->count) {
473  ((BMIter *)iter)->count--;
474  iter->l_next = bmesh_radial_faceloop_find_next(iter->l_next, iter->vdata);
475  if (iter->l_next == iter->l_first) {
476  iter->e_next = bmesh_disk_faceedge_find_next(iter->e_next, iter->vdata);
477  iter->l_first = bmesh_radial_faceloop_find_first(iter->e_next->l, iter->vdata);
478  iter->l_next = iter->l_first;
479  }
480  }
481 
482  if (!((BMIter *)iter)->count) {
483  iter->l_next = NULL;
484  }
485 
486  /* NULL on finish */
487  return l_curr;
488 }
489 
490 /*
491  * LOOP OF EDGE CALLBACKS
492  */
493 
495 {
496  iter->l_first = iter->l_next = iter->edata->l;
497 }
498 
500 {
501  BMLoop *l_curr = iter->l_next;
502 
503  if (iter->l_next) {
504  iter->l_next = iter->l_next->radial_next;
505  if (iter->l_next == iter->l_first) {
506  iter->l_next = NULL;
507  }
508  }
509 
510  /* NULL on finish */
511  return l_curr;
512 }
513 
514 /*
515  * LOOP OF LOOP CALLBACKS
516  */
517 
519 {
520  iter->l_first = iter->ldata;
521  iter->l_next = iter->l_first->radial_next;
522 
523  if (iter->l_next == iter->l_first) {
524  iter->l_next = NULL;
525  }
526 }
527 
529 {
530  BMLoop *l_curr = iter->l_next;
531 
532  if (iter->l_next) {
533  iter->l_next = iter->l_next->radial_next;
534  if (iter->l_next == iter->l_first) {
535  iter->l_next = NULL;
536  }
537  }
538 
539  /* NULL on finish */
540  return l_curr;
541 }
542 
543 /*
544  * FACE OF EDGE CALLBACKS
545  */
546 
548 {
549  iter->l_first = iter->l_next = iter->edata->l;
550 }
551 
553 {
554  BMLoop *current = iter->l_next;
555 
556  if (iter->l_next) {
557  iter->l_next = iter->l_next->radial_next;
558  if (iter->l_next == iter->l_first) {
559  iter->l_next = NULL;
560  }
561  }
562 
563  return current ? current->f : NULL;
564 }
565 
566 /*
567  * VERTS OF EDGE CALLBACKS
568  */
569 
571 {
572  ((BMIter *)iter)->count = 0;
573 }
574 
576 {
577  switch (((BMIter *)iter)->count++) {
578  case 0:
579  return iter->edata->v1;
580  case 1:
581  return iter->edata->v2;
582  default:
583  return NULL;
584  }
585 }
586 
587 /*
588  * VERT OF FACE CALLBACKS
589  */
590 
592 {
593  iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
594 }
595 
597 {
598  BMLoop *l_curr = iter->l_next;
599 
600  if (iter->l_next) {
601  iter->l_next = iter->l_next->next;
602  if (iter->l_next == iter->l_first) {
603  iter->l_next = NULL;
604  }
605  }
606 
607  return l_curr ? l_curr->v : NULL;
608 }
609 
610 /*
611  * EDGE OF FACE CALLBACKS
612  */
613 
615 {
616  iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
617 }
618 
620 {
621  BMLoop *l_curr = iter->l_next;
622 
623  if (iter->l_next) {
624  iter->l_next = iter->l_next->next;
625  if (iter->l_next == iter->l_first) {
626  iter->l_next = NULL;
627  }
628  }
629 
630  return l_curr ? l_curr->e : NULL;
631 }
632 
633 /*
634  * LOOP OF FACE CALLBACKS
635  */
636 
638 {
639  iter->l_first = iter->l_next = BM_FACE_FIRST_LOOP(iter->pdata);
640 }
641 
643 {
644  BMLoop *l_curr = iter->l_next;
645 
646  if (iter->l_next) {
647  iter->l_next = iter->l_next->next;
648  if (iter->l_next == iter->l_first) {
649  iter->l_next = NULL;
650  }
651  }
652 
653  return l_curr;
654 }
#define BLI_assert(a)
Definition: BLI_assert.h:46
#define BLI_BITMAP_ENABLE(_bitmap, _index)
Definition: BLI_bitmap.h:81
#define BLI_BITMAP_DISABLE(_bitmap, _index)
Definition: BLI_bitmap.h:88
unsigned int BLI_bitmap
Definition: BLI_bitmap.h:16
void BLI_mempool_iternew(BLI_mempool *pool, BLI_mempool_iter *iter) ATTR_NONNULL()
Definition: BLI_mempool.c:498
void * BLI_mempool_iterstep(BLI_mempool_iter *iter) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
Definition: BLI_mempool.c:577
int BLI_mempool_len(const BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:434
Read Guarded memory(de)allocation.
#define MEM_reallocN(vmemh, len)
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
@ BM_EDGE
Definition: bmesh_class.h:384
#define BM_elem_flag_test_bool(ele, hflag)
Definition: bmesh_inline.h:13
int BMO_iter_elem_count_flag(BMesh *bm, const char itype, void *data, const short oflag, const bool value)
Elem Iter Tool Flag Count.
void * bmiter__loop_of_face_step(struct BMIter__loop_of_face *iter)
void * BM_iter_as_arrayN(BMesh *bm, const char itype, void *data, int *r_len, void **stack_array, int stack_array_size)
Iterator as Array.
void bmiter__loop_of_loop_begin(struct BMIter__loop_of_loop *iter)
void * bmiter__vert_of_edge_step(struct BMIter__vert_of_edge *iter)
int BMO_iter_as_array(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, void **array, const int len)
Operator Iterator as Array.
void * bmiter__edge_of_face_step(struct BMIter__edge_of_face *iter)
void * bmiter__elem_of_mesh_step(struct BMIter__elem_of_mesh *iter)
const char bm_iter_itype_htype_map[BM_ITYPE_MAX]
int BM_iter_mesh_bitmap_from_filter_tessface(BMesh *bm, BLI_bitmap *bitmap, bool(*test_fn)(BMFace *, void *user_data), void *user_data)
void bmiter__edge_of_face_begin(struct BMIter__edge_of_face *iter)
void bmiter__loop_of_vert_begin(struct BMIter__loop_of_vert *iter)
void bmiter__face_of_edge_begin(struct BMIter__face_of_edge *iter)
void bmiter__loop_of_face_begin(struct BMIter__loop_of_face *iter)
void * BMO_iter_as_arrayN(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char restrictmask, int *r_len, void **stack_array, int stack_array_size)
void * bmiter__loop_of_loop_step(struct BMIter__loop_of_loop *iter)
void bmiter__vert_of_face_begin(struct BMIter__vert_of_face *iter)
int BM_iter_mesh_bitmap_from_filter(const char itype, BMesh *bm, BLI_bitmap *bitmap, bool(*test_fn)(BMElem *, void *user_data), void *user_data)
void * BM_iter_at_index(BMesh *bm, const char itype, void *data, int index)
void * bmiter__loop_of_edge_step(struct BMIter__loop_of_edge *iter)
int BM_iter_mesh_count_flag(const char itype, BMesh *bm, const char hflag, const bool value)
Mesh Iter Flag Count.
void bmiter__face_of_vert_begin(struct BMIter__face_of_vert *iter)
void bmiter__elem_of_mesh_begin(struct BMIter__elem_of_mesh *iter)
void bmiter__edge_of_vert_begin(struct BMIter__edge_of_vert *iter)
void bmiter__loop_of_edge_begin(struct BMIter__loop_of_edge *iter)
int BM_iter_as_array(BMesh *bm, const char itype, void *data, void **array, const int len)
Iterator as Array.
void * bmiter__face_of_edge_step(struct BMIter__face_of_edge *iter)
void bmiter__vert_of_edge_begin(struct BMIter__vert_of_edge *iter)
void * bmiter__vert_of_face_step(struct BMIter__vert_of_face *iter)
int BM_iter_mesh_count(const char itype, BMesh *bm)
int BM_iter_elem_count_flag(const char itype, void *data, const char hflag, const bool value)
Elem Iter Flag Count.
void * bmiter__face_of_vert_step(struct BMIter__face_of_vert *iter)
void * bmiter__loop_of_vert_step(struct BMIter__loop_of_vert *iter)
void * bmiter__edge_of_vert_step(struct BMIter__edge_of_vert *iter)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
@ BM_EDGES_OF_MESH
@ BM_VERTS_OF_MESH
@ BM_FACES_OF_MESH
#define BM_iter_new(iter, bm, itype, data)
#define BM_ITYPE_MAX
BLI_INLINE bool BM_iter_init(BMIter *iter, BMesh *bm, const char itype, void *data)
Iterator Init.
ATTR_WARN_UNUSED_RESULT BMesh const char itype
ATTR_WARN_UNUSED_RESULT BMesh * bm
#define BMO_edge_flag_test_bool(bm, e, oflag)
#define BMO_face_flag_test_bool(bm, e, oflag)
void * BMO_iter_step(BMOIter *iter)
void * BMO_iter_new(BMOIter *iter, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char restrictmask)
New Iterator.
#define BMO_OP_MAX_SLOTS
int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_vert_flag_test_bool(bm, e, oflag)
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
BMLoop * bmesh_disk_faceloop_find_first(const BMEdge *e, const BMVert *v)
BMEdge * bmesh_disk_faceedge_find_next(const BMEdge *e, const BMVert *v)
BMLoop * bmesh_radial_faceloop_find_next(const BMLoop *l, const BMVert *v)
BMLoop * bmesh_radial_faceloop_find_first(const BMLoop *l, const BMVert *v)
BME RADIAL FIND FIRST FACE VERT.
int bmesh_disk_facevert_count(const BMVert *v)
DISK COUNT FACE VERT.
BLI_INLINE BMEdge * bmesh_disk_edge_next(const BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
void * user_data
int len
Definition: draw_manager.c:108
int count
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
BLI_mempool * pool
Definition: BLI_mempool.h:92
BMVert * v1
Definition: bmesh_class.h:122
BMVert * v2
Definition: bmesh_class.h:122
struct BMLoop * l
Definition: bmesh_class.h:128
int len
Definition: bmesh_class.h:267
BLI_mempool_iter pooliter
struct BMVert * v
Definition: bmesh_class.h:153
struct BMEdge * e
Definition: bmesh_class.h:164
struct BMLoop * radial_next
Definition: bmesh_class.h:204
struct BMFace * f
Definition: bmesh_class.h:171
struct BMLoop * next
Definition: bmesh_class.h:233
struct BMEdge * e
Definition: bmesh_class.h:97
int totvert
Definition: bmesh_class.h:297
int totedge
Definition: bmesh_class.h:297
int totface
Definition: bmesh_class.h:297