Blender  V2.93
bmo_fill_attribute.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 "BLI_linklist_stack.h"
24 #include "BLI_utildefines.h"
25 
26 #include "bmesh.h"
27 
28 #include "intern/bmesh_operators_private.h" /* own include */
29 
34 {
35  BMLoop *l_iter;
36  l_iter = l->radial_next;
37  do {
38  if (BM_elem_flag_test(l_iter->f, BM_ELEM_TAG) == 0) {
39  return false;
40  }
41  } while ((l_iter = l_iter->radial_next) != l);
42 
43  return true;
44 }
45 
49 static bool bm_loop_is_face_untag(const BMLoop *l, void *UNUSED(user_data))
50 {
51  return (BM_elem_flag_test(l->f, BM_ELEM_TAG) == 0);
52 }
53 
58  BMLoop *l,
59  const bool use_normals,
60  const bool use_data)
61 {
62  BMLoop *l_other = l->radial_next;
63  BMFace *f = l->f, *f_other;
64  while (BM_elem_flag_test(l_other->f, BM_ELEM_TAG)) {
65  l_other = l_other->radial_next;
66  }
67  f_other = l_other->f;
68 
69  if (use_data) {
70  /* copy face-attrs */
71  BM_elem_attrs_copy(bm, bm, f_other, f);
72 
73  /* copy loop-attrs */
75  }
76 
77  if (use_normals) {
78  /* copy winding (flipping) */
79  if (l->v == l_other->v) {
81  }
82  }
83 }
84 
88 static uint bmesh_face_attribute_fill(BMesh *bm, const bool use_normals, const bool use_data)
89 {
90  BLI_LINKSTACK_DECLARE(loop_queue_prev, BMLoop *);
91  BLI_LINKSTACK_DECLARE(loop_queue_next, BMLoop *);
92 
93  BMFace *f;
94  BMIter iter;
95  BMLoop *l;
96 
97  uint face_tot = 0;
98 
99  BLI_LINKSTACK_INIT(loop_queue_prev);
100  BLI_LINKSTACK_INIT(loop_queue_next);
101 
102  BM_ITER_MESH (f, &iter, bm, BM_FACES_OF_MESH) {
103  if (BM_elem_flag_test(f, BM_ELEM_TAG)) {
104  BMLoop *l_iter, *l_first;
105  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
106  do {
107  if (bm_loop_is_all_radial_tag(l_iter) == false) {
108  BLI_LINKSTACK_PUSH(loop_queue_prev, l_iter);
109  }
110  } while ((l_iter = l_iter->next) != l_first);
111  }
112  }
113 
114  while (BLI_LINKSTACK_SIZE(loop_queue_prev)) {
115  while ((l = BLI_LINKSTACK_POP(loop_queue_prev))) {
116  /* check we're still un-assigned */
117  if (BM_elem_flag_test(l->f, BM_ELEM_TAG)) {
118  BMLoop *l_iter;
119 
121 
122  l_iter = l->next;
123  do {
124  BMLoop *l_radial_iter = l_iter->radial_next;
125  if (l_radial_iter != l_iter) {
126  do {
127  if (BM_elem_flag_test(l_radial_iter->f, BM_ELEM_TAG)) {
128  BLI_LINKSTACK_PUSH(loop_queue_next, l_radial_iter);
129  }
130  } while ((l_radial_iter = l_radial_iter->radial_next) != l_iter);
131  }
132  } while ((l_iter = l_iter->next) != l);
133 
134  /* do last because of face flipping */
135  bm_face_copy_shared_all(bm, l, use_normals, use_data);
136  face_tot += 1;
137  }
138  }
139 
140  BLI_LINKSTACK_SWAP(loop_queue_prev, loop_queue_next);
141  }
142 
143  BLI_LINKSTACK_FREE(loop_queue_prev);
144  BLI_LINKSTACK_FREE(loop_queue_next);
145 
146  return face_tot;
147 }
148 
150 {
151  const bool use_normals = BMO_slot_bool_get(op->slots_in, "use_normals");
152  const bool use_data = BMO_slot_bool_get(op->slots_in, "use_data");
153 
154  int face_tot;
155 
158  bm, op->slots_in, "faces", BM_FACE, BM_ELEM_TAG, false); /* do inline */
159 
160  /* now we can copy adjacent data */
161  face_tot = bmesh_face_attribute_fill(bm, use_normals, use_data);
162 
163  if (face_tot != BMO_slot_buffer_count(op->slots_in, "faces")) {
164  /* any remaining tags will be skipped */
166  bm, op, op->slots_out, "faces_fail.out", BM_FACE, BM_ELEM_TAG);
167  }
168 }
unsigned int uint
Definition: BLI_sys_types.h:83
#define UNUSED(x)
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_ELEM_TAG
Definition: bmesh_class.h:484
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
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:29
#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
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, const char htype, const char hflag, const 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, const char htype, const char hflag)
int BMO_slot_buffer_count(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:165
struct BMLoop * radial_next
Definition: bmesh_class.h:216
struct BMFace * f
Definition: bmesh_class.h:183
struct BMLoop * next
Definition: bmesh_class.h:245
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]