Blender  V2.93
bmesh_triangulate.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 "DNA_modifier_types.h" /* for MOD_TRIANGULATE_NGON_BEAUTY only */
24 
25 #include "MEM_guardedalloc.h"
26 
27 #include "BLI_alloca.h"
28 #include "BLI_heap.h"
29 #include "BLI_linklist.h"
30 #include "BLI_memarena.h"
31 #include "BLI_utildefines.h"
32 
33 /* only for defines */
34 #include "BLI_polyfill_2d.h"
36 
37 #include "bmesh.h"
38 
39 #include "bmesh_triangulate.h" /* own include */
40 
45  BMFace *face,
46  const int quad_method,
47  const int ngon_method,
48  const bool use_tag,
49  BMOperator *op,
50  BMOpSlot *slot_facemap_out,
51  BMOpSlot *slot_facemap_double_out,
52 
53  MemArena *pf_arena,
54  /* use for MOD_TRIANGULATE_NGON_BEAUTY only! */
55  struct Heap *pf_heap)
56 {
57  int faces_array_tot = face->len - 3;
58  BMFace **faces_array = BLI_array_alloca(faces_array, faces_array_tot);
59  LinkNode *faces_double = NULL;
60  BLI_assert(face->len > 3);
61 
63  face,
64  faces_array,
65  &faces_array_tot,
66  NULL,
67  NULL,
68  &faces_double,
69  quad_method,
70  ngon_method,
71  use_tag,
72  pf_arena,
73  pf_heap);
74 
75  if (faces_array_tot) {
76  int i;
77  BMO_slot_map_elem_insert(op, slot_facemap_out, face, face);
78  for (i = 0; i < faces_array_tot; i++) {
79  BMO_slot_map_elem_insert(op, slot_facemap_out, faces_array[i], face);
80  }
81 
82  while (faces_double) {
83  LinkNode *next = faces_double->next;
84  BMO_slot_map_elem_insert(op, slot_facemap_double_out, faces_double->link, face);
85  MEM_freeN(faces_double);
86  faces_double = next;
87  }
88  }
89 }
90 
92  const int quad_method,
93  const int ngon_method,
94  const int min_vertices,
95  const bool tag_only,
96  BMOperator *op,
97  BMOpSlot *slot_facemap_out,
98  BMOpSlot *slot_facemap_double_out)
99 {
100  BMIter iter;
101  BMFace *face;
102  MemArena *pf_arena;
103  Heap *pf_heap;
104 
105  pf_arena = BLI_memarena_new(BLI_POLYFILL_ARENA_SIZE, __func__);
106 
107  if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) {
109  }
110  else {
111  pf_heap = NULL;
112  }
113 
114  if (slot_facemap_out) {
115  /* same as below but call: bm_face_triangulate_mapping() */
116  BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
117  if (face->len >= min_vertices) {
118  if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
120  face,
121  quad_method,
122  ngon_method,
123  tag_only,
124  op,
125  slot_facemap_out,
126  slot_facemap_double_out,
127  pf_arena,
128  pf_heap);
129  }
130  }
131  }
132  }
133  else {
134  LinkNode *faces_double = NULL;
135 
136  BM_ITER_MESH (face, &iter, bm, BM_FACES_OF_MESH) {
137  if (face->len >= min_vertices) {
138  if (tag_only == false || BM_elem_flag_test(face, BM_ELEM_TAG)) {
140  face,
141  NULL,
142  NULL,
143  NULL,
144  NULL,
145  &faces_double,
146  quad_method,
147  ngon_method,
148  tag_only,
149  pf_arena,
150  pf_heap);
151  }
152  }
153  }
154 
155  while (faces_double) {
156  LinkNode *next = faces_double->next;
157  BM_face_kill(bm, faces_double->link);
158  MEM_freeN(faces_double);
159  faces_double = next;
160  }
161  }
162 
163  BLI_memarena_free(pf_arena);
164 
165  if (ngon_method == MOD_TRIANGULATE_NGON_BEAUTY) {
166  BLI_heap_free(pf_heap, NULL);
167  }
168 }
#define BLI_array_alloca(arr, realsize)
Definition: BLI_alloca.h:36
#define BLI_assert(a)
Definition: BLI_assert.h:58
A min-heap / priority queue ADT.
void BLI_heap_free(Heap *heap, HeapFreeFP ptrfreefp) ATTR_NONNULL(1)
Definition: BLI_heap.c:221
Heap * BLI_heap_new_ex(unsigned int tot_reserve) ATTR_WARN_UNUSED_RESULT
Definition: BLI_heap.c:201
void BLI_memarena_free(struct MemArena *ma) ATTR_NONNULL(1)
Definition: BLI_memarena.c:109
struct MemArena * BLI_memarena_new(const size_t bufsize, const char *name) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(2) ATTR_MALLOC
Definition: BLI_memarena.c:79
#define BLI_POLYFILL_ARENA_SIZE
#define BLI_POLYFILL_ALLOC_NGON_RESERVE
@ MOD_TRIANGULATE_NGON_BEAUTY
Read Guarded memory(de)allocation.
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_face_kill(BMesh *bm, BMFace *f)
Definition: bmesh_core.c:881
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:26
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op, BMOpSlot *slot, const void *element, void *val)
void BM_face_triangulate(BMesh *bm, BMFace *f, BMFace **r_faces_new, int *r_faces_new_tot, BMEdge **r_edges_new, int *r_edges_new_tot, LinkNode **r_faces_double, const int quad_method, const int ngon_method, const bool use_tag, MemArena *pf_arena, struct Heap *pf_heap)
BMESH TRIANGULATE FACE.
void BM_mesh_triangulate(BMesh *bm, const int quad_method, const int ngon_method, const int min_vertices, const bool tag_only, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out)
static void bm_face_triangulate_mapping(BMesh *bm, BMFace *face, const int quad_method, const int ngon_method, const bool use_tag, BMOperator *op, BMOpSlot *slot_facemap_out, BMOpSlot *slot_facemap_double_out, MemArena *pf_arena, struct Heap *pf_heap)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:41
static ulong * next
int len
Definition: bmesh_class.h:279
Definition: BLI_heap.c:57
void * link
Definition: BLI_linklist.h:40
struct LinkNode * next
Definition: BLI_linklist.h:39