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
17 /** \file
18 * \ingroup bmesh
19 *
20 * BMesh inline operator functions.
21 */
22
23 #pragma once
24
25 /* tool flag API. never, ever ever should tool code put junk in
26 * header flags (element->head.flag), nor should they use
27 * element->head.eflag1/eflag2. instead, use this api to set
28 * flags.
29 *
30 * if you need to store a value per element, use a
31 * ghash or a mapping slot to do it. */
32
33 /* flags 15 and 16 (1 << 14 and 1 << 15) are reserved for bmesh api use */
34 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
_bmo_elem_flag_test(BMesh * bm,const BMFlagLayer * oflags,const short oflag)35 short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
36 {
37 BLI_assert(bm->use_toolflags);
38 return oflags[bm->toolflag_index].f & oflag;
39 }
40
41 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2) BLI_INLINE
_bmo_elem_flag_test_bool(BMesh * bm,const BMFlagLayer * oflags,const short oflag)42 bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
43 {
44 BLI_assert(bm->use_toolflags);
45 return (oflags[bm->toolflag_index].f & oflag) != 0;
46 }
47
48 ATTR_NONNULL(1, 2)
_bmo_elem_flag_enable(BMesh * bm,BMFlagLayer * oflags,const short oflag)49 BLI_INLINE void _bmo_elem_flag_enable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
50 {
51 BLI_assert(bm->use_toolflags);
52 oflags[bm->toolflag_index].f |= oflag;
53 }
54
55 ATTR_NONNULL(1, 2)
_bmo_elem_flag_disable(BMesh * bm,BMFlagLayer * oflags,const short oflag)56 BLI_INLINE void _bmo_elem_flag_disable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
57 {
58 BLI_assert(bm->use_toolflags);
59 oflags[bm->toolflag_index].f &= (short)~oflag;
60 }
61
62 ATTR_NONNULL(1, 2)
_bmo_elem_flag_set(BMesh * bm,BMFlagLayer * oflags,const short oflag,int val)63 BLI_INLINE void _bmo_elem_flag_set(BMesh *bm, BMFlagLayer *oflags, const short oflag, int val)
64 {
65 BLI_assert(bm->use_toolflags);
66 if (val) {
67 oflags[bm->toolflag_index].f |= oflag;
68 }
69 else {
70 oflags[bm->toolflag_index].f &= (short)~oflag;
71 }
72 }
73
74 ATTR_NONNULL(1, 2)
_bmo_elem_flag_toggle(BMesh * bm,BMFlagLayer * oflags,const short oflag)75 BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const short oflag)
76 {
77 BLI_assert(bm->use_toolflags);
78 oflags[bm->toolflag_index].f ^= oflag;
79 }
80
81 ATTR_NONNULL(1, 2)
BMO_slot_map_int_insert(BMOperator * op,BMOpSlot * slot,void * element,const int val)82 BLI_INLINE void BMO_slot_map_int_insert(BMOperator *op,
83 BMOpSlot *slot,
84 void *element,
85 const int val)
86 {
87 union {
88 void *ptr;
89 int val;
90 } t = {NULL};
91 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
92 BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
93 }
94
95 ATTR_NONNULL(1, 2)
BMO_slot_map_bool_insert(BMOperator * op,BMOpSlot * slot,void * element,const bool val)96 BLI_INLINE void BMO_slot_map_bool_insert(BMOperator *op,
97 BMOpSlot *slot,
98 void *element,
99 const bool val)
100 {
101 union {
102 void *ptr;
103 bool val;
104 } t = {NULL};
105 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
106 BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
107 }
108
109 ATTR_NONNULL(1, 2)
BMO_slot_map_float_insert(BMOperator * op,BMOpSlot * slot,void * element,const float val)110 BLI_INLINE void BMO_slot_map_float_insert(BMOperator *op,
111 BMOpSlot *slot,
112 void *element,
113 const float val)
114 {
115 union {
116 void *ptr;
117 float val;
118 } t = {NULL};
119 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
120 BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
121 }
122
123 /* pointer versions of BMO_slot_map_float_get and BMO_slot_map_float_insert.
124 *
125 * do NOT use these for non-operator-api-allocated memory! instead
126 * use BMO_slot_map_data_get and BMO_slot_map_insert, which copies the data. */
127
128 ATTR_NONNULL(1, 2)
BMO_slot_map_ptr_insert(BMOperator * op,BMOpSlot * slot,const void * element,void * val)129 BLI_INLINE void BMO_slot_map_ptr_insert(BMOperator *op,
130 BMOpSlot *slot,
131 const void *element,
132 void *val)
133 {
134 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
135 BMO_slot_map_insert(op, slot, element, val);
136 }
137
138 ATTR_NONNULL(1, 2)
BMO_slot_map_elem_insert(BMOperator * op,BMOpSlot * slot,const void * element,void * val)139 BLI_INLINE void BMO_slot_map_elem_insert(BMOperator *op,
140 BMOpSlot *slot,
141 const void *element,
142 void *val)
143 {
144 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
145 BMO_slot_map_insert(op, slot, element, val);
146 }
147
148 /* no values */
149 ATTR_NONNULL(1, 2)
BMO_slot_map_empty_insert(BMOperator * op,BMOpSlot * slot,const void * element)150 BLI_INLINE void BMO_slot_map_empty_insert(BMOperator *op, BMOpSlot *slot, const void *element)
151 {
152 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
153 BMO_slot_map_insert(op, slot, element, NULL);
154 }
155
156 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_contains(BMOpSlot * slot,const void * element)157 bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
158 {
159 BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
160 return BLI_ghash_haskey(slot->data.ghash, element);
161 }
162
163 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_data_get(BMOpSlot * slot,const void * element)164 void **BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
165 {
166
167 return BLI_ghash_lookup_p(slot->data.ghash, element);
168 }
169
170 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_float_get(BMOpSlot * slot,const void * element)171 float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
172 {
173 void **data;
174 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
175
176 data = BMO_slot_map_data_get(slot, element);
177 if (data) {
178 return *(float *)data;
179 }
180 else {
181 return 0.0f;
182 }
183 }
184
185 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_int_get(BMOpSlot * slot,const void * element)186 int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
187 {
188 void **data;
189 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
190
191 data = BMO_slot_map_data_get(slot, element);
192 if (data) {
193 return *(int *)data;
194 }
195 else {
196 return 0;
197 }
198 }
199
200 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_bool_get(BMOpSlot * slot,const void * element)201 bool BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
202 {
203 void **data;
204 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
205
206 data = BMO_slot_map_data_get(slot, element);
207 if (data) {
208 return *(bool *)data;
209 }
210 else {
211 return false;
212 }
213 }
214
215 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_ptr_get(BMOpSlot * slot,const void * element)216 void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
217 {
218 void **val = BMO_slot_map_data_get(slot, element);
219 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
220 if (val) {
221 return *val;
222 }
223
224 return NULL;
225 }
226
227 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1) BLI_INLINE
BMO_slot_map_elem_get(BMOpSlot * slot,const void * element)228 void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
229 {
230 void **val = (void **)BMO_slot_map_data_get(slot, element);
231 BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
232 if (val) {
233 return *val;
234 }
235
236 return NULL;
237 }
238