Blender  V3.3
bmo_fill_attribute.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include "BLI_linklist_stack.h"
10 #include "BLI_utildefines.h"
11 
12 #include "bmesh.h"
13 
14 #include "intern/bmesh_operators_private.h" /* own include */
15 
20 {
21  BMLoop *l_iter;
22  l_iter = l->radial_next;
23  do {
24  if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) == 0) {
25  return false;
26  }
27  } while ((l_iter = l_iter->radial_next) != l);
28 
29  return true;
30 }
31 
35 static bool bm_loop_is_face_untag(const BMLoop *l, void *UNUSED(user_data))
36 {
37  return (BM_elem_flag_test(l->f, BM_ELEM_TAG) == 0);
38 }
39 
44  BMLoop *l,
45  const bool use_normals,
46  const bool use_data)
47 {
48  BMLoop *l_other = l->radial_next;
49  BMFace *f = l->f, *f_other;
50  while (BM_elem_flag_test(l_other->f, BM_ELEM_TAG)) {
51  l_other = l_other->radial_next;
52  }
53  f_other = l_other->f;
54 
55  if (use_data) {
56  /* copy face-attrs */
57  BM_elem_attrs_copy(bm, bm, f_other, f);
58 
59  /* copy loop-attrs */
61  }
62 
63  if (use_normals) {
64  /* copy winding (flipping) */
65  if (l->v == l_other->v) {
67  }
68  }
69 }
70 
74 static uint bmesh_face_attribute_fill(BMesh *bm, const bool use_normals, const bool use_data)
75 {
76  BLI_LINKSTACK_DECLARE(loop_queue_prev, BMLoop *);
77  BLI_LINKSTACK_DECLARE(loop_queue_next, BMLoop *);
78 
79  BMFace *f;
80  BMIter iter;
81  BMLoop *l;
82 
83  uint face_tot = 0;
84 
85  BLI_LINKSTACK_INIT(loop_queue_prev);
86  BLI_LINKSTACK_INIT(loop_queue_next);
87 
88  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
90  BMLoop *l_iter, *l_first;
91  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
92  do {
93  if (bm_loop_is_all_radial_tag(l_iter) == false) {
94  BLI_LINKSTACK_PUSH(loop_queue_prev, l_iter);
95  }
96  } while ((l_iter = l_iter->next) != l_first);
97  }
98  }
99 
100  while (BLI_LINKSTACK_SIZE(loop_queue_prev)) {
101  while ((l = BLI_LINKSTACK_POP(loop_queue_prev))) {
102  /* check we're still un-assigned */
103  if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
104  BMLoop *l_iter;
105 
107 
108  l_iter = l->next;
109  do {
110  BMLoop *l_radial_iter = l_iter->radial_next;
111  if (l_radial_iter != l_iter) {
112  do {
113  if (BM_elem_flag_test(l_radial_iter->f, BM_ELEM_TAG)) {
114  BLI_LINKSTACK_PUSH(loop_queue_next, l_radial_iter);
115  }
116  } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
117  }
118  } while ((l_iter = l_iter->next) != l);
119 
120  /* do last because of face flipping */
121  bm_face_copy_shared_all(bm, l, use_normals, use_data);
122  face_tot += 1;
123  }
124  }
125 
126  BLI_LINKSTACK_SWAP(loop_queue_prev, loop_queue_next);
127  }
128 
129  BLI_LINKSTACK_FREE(loop_queue_prev);
130  BLI_LINKSTACK_FREE(loop_queue_next);
131 
132  return face_tot;
133 }
134 
136 {
137  const bool use_normals = BMO_slot_bool_get(op->slots_in, "use_normals");
138  const bool use_data = BMO_slot_bool_get(op->slots_in, "use_data");
139 
140  int face_tot;
141 
143 
144  /* do inline */
146 
147  /* now we can copy adjacent data */
148  face_tot = bmesh_face_attribute_fill(bm, use_normals, use_data);
149 
150  if (face_tot != BMO_slot_buffer_len(op->slots_in, "faces")) {
151  /* any remaining tags will be skipped */
153  bm, op, op->slots_out, "faces_fail.out", BM_FACE, BM_ELEM_TAG);
154  }
155 }
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
void BM_face_copy_shared(BMesh *bm, BMFace *f, BMLoopFilterFunc filter_fn, void *user_data)
copies face loop data from shared adjacent faces.
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_dst)
#define BM_elem_flag_disable(ele, hflag)
Definition: bmesh_inline.h:15
#define BM_elem_flag_test(ele, hflag)
Definition: bmesh_inline.h:12
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_FACES_OF_MESH
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_hflag_disable_all(BMesh *bm, const char htype, const char hflag, const bool respecthide)
void BMO_slot_buffer_hflag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag, bool do_flush)
BMO_FLAG_BUFFER.
void BMO_slot_buffer_from_enabled_hflag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, char hflag)
int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
void BM_face_normal_flip(BMesh *bm, BMFace *f)
ATTR_WARN_UNUSED_RESULT const BMLoop * l
void bmo_face_attribute_fill_exec(BMesh *bm, BMOperator *op)
static bool bm_loop_is_all_radial_tag(BMLoop *l)
static bool bm_loop_is_face_untag(const BMLoop *l, void *UNUSED(user_data))
static uint bmesh_face_attribute_fill(BMesh *bm, const bool use_normals, const bool use_data)
static void bm_face_copy_shared_all(BMesh *bm, BMLoop *l, const bool use_normals, const bool use_data)
void * user_data
struct BMVert * v
Definition: bmesh_class.h:153
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 BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]