Merge branch 'master' into blender2.8
[blender.git] / source / blender / bmesh / intern / bmesh_operator_api_inline.h
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Joseph Eagar, Geoffrey Bantle, Campbell Barton
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file blender/bmesh/intern/bmesh_operator_api_inline.h
24  *  \ingroup bmesh
25  *
26  * BMesh inline operator functions.
27  */
28
29 #ifndef __BMESH_OPERATOR_API_INLINE_H__
30 #define __BMESH_OPERATOR_API_INLINE_H__
31
32 /* tool flag API. never, ever ever should tool code put junk in
33  * header flags (element->head.flag), nor should they use
34  * element->head.eflag1/eflag2.  instead, use this api to set
35  * flags.
36  *
37  * if you need to store a value per element, use a
38  * ghash or a mapping slot to do it. */
39
40 /* flags 15 and 16 (1 << 14 and 1 << 15) are reserved for bmesh api use */
41 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
42 BLI_INLINE short _bmo_elem_flag_test(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
43 {
44         BLI_assert(bm->use_toolflags);
45         return oflags[bm->toolflag_index].f & oflag;
46 }
47
48 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1, 2)
49 BLI_INLINE bool _bmo_elem_flag_test_bool(BMesh *bm, const BMFlagLayer *oflags, const short oflag)
50 {
51         BLI_assert(bm->use_toolflags);
52         return (oflags[bm->toolflag_index].f & oflag) != 0;
53 }
54
55 ATTR_NONNULL(1, 2)
56 BLI_INLINE void _bmo_elem_flag_enable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
57 {
58         BLI_assert(bm->use_toolflags);
59         oflags[bm->toolflag_index].f |= oflag;
60 }
61
62 ATTR_NONNULL(1, 2)
63 BLI_INLINE void _bmo_elem_flag_disable(BMesh *bm, BMFlagLayer *oflags, const short oflag)
64 {
65         BLI_assert(bm->use_toolflags);
66         oflags[bm->toolflag_index].f &= (short)~oflag;
67 }
68
69 ATTR_NONNULL(1, 2)
70 BLI_INLINE void _bmo_elem_flag_set(BMesh *bm, BMFlagLayer *oflags, const short oflag, int val)
71 {
72         BLI_assert(bm->use_toolflags);
73         if (val) oflags[bm->toolflag_index].f |= oflag;
74         else     oflags[bm->toolflag_index].f &= (short)~oflag;
75 }
76
77 ATTR_NONNULL(1, 2)
78 BLI_INLINE void _bmo_elem_flag_toggle(BMesh *bm, BMFlagLayer *oflags, const short oflag)
79 {
80         BLI_assert(bm->use_toolflags);
81         oflags[bm->toolflag_index].f ^= oflag;
82 }
83
84 ATTR_NONNULL(1, 2)
85 BLI_INLINE void BMO_slot_map_int_insert(
86         BMOperator *op, BMOpSlot *slot,
87         void *element, const int val)
88 {
89         union { void *ptr; int val; } t = {NULL};
90         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
91         BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
92 }
93
94 ATTR_NONNULL(1, 2)
95 BLI_INLINE void BMO_slot_map_bool_insert(
96         BMOperator *op, BMOpSlot *slot,
97         void *element, const bool val)
98 {
99         union { void *ptr; bool val; } t = {NULL};
100         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
101         BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
102 }
103
104 ATTR_NONNULL(1, 2)
105 BLI_INLINE void BMO_slot_map_float_insert(
106         BMOperator *op, BMOpSlot *slot,
107         void *element, const float val)
108 {
109         union { void *ptr; float val; } t = {NULL};
110         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
111         BMO_slot_map_insert(op, slot, element, ((void)(t.val = val), t.ptr));
112 }
113
114
115 /* pointer versions of BMO_slot_map_float_get and BMO_slot_map_float_insert.
116  *
117  * do NOT use these for non-operator-api-allocated memory! instead
118  * use BMO_slot_map_data_get and BMO_slot_map_insert, which copies the data. */
119
120 ATTR_NONNULL(1, 2)
121 BLI_INLINE void BMO_slot_map_ptr_insert(
122         BMOperator *op, BMOpSlot *slot,
123         const void *element, void *val)
124 {
125         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
126         BMO_slot_map_insert(op, slot, element, val);
127 }
128
129 ATTR_NONNULL(1, 2)
130 BLI_INLINE void BMO_slot_map_elem_insert(
131         BMOperator *op, BMOpSlot *slot,
132         const void *element, void *val)
133 {
134         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
135         BMO_slot_map_insert(op, slot, element, val);
136 }
137
138
139 /* no values */
140 ATTR_NONNULL(1, 2)
141 BLI_INLINE void BMO_slot_map_empty_insert(
142         BMOperator *op, BMOpSlot *slot,
143         const void *element)
144 {
145         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_EMPTY);
146         BMO_slot_map_insert(op, slot, element, NULL);
147 }
148
149 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
150 BLI_INLINE bool BMO_slot_map_contains(BMOpSlot *slot, const void *element)
151 {
152         BLI_assert(slot->slot_type == BMO_OP_SLOT_MAPPING);
153         return BLI_ghash_haskey(slot->data.ghash, element);
154 }
155
156 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
157 BLI_INLINE void **BMO_slot_map_data_get(BMOpSlot *slot, const void *element)
158 {
159
160         return BLI_ghash_lookup_p(slot->data.ghash, element);
161 }
162
163 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
164 BLI_INLINE float BMO_slot_map_float_get(BMOpSlot *slot, const void *element)
165 {
166         void **data;
167         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_FLT);
168
169         data = BMO_slot_map_data_get(slot, element);
170         if (data) {
171                 return *(float *)data;
172         }
173         else {
174                 return 0.0f;
175         }
176 }
177
178 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
179 BLI_INLINE int BMO_slot_map_int_get(BMOpSlot *slot, const void *element)
180 {
181         void **data;
182         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INT);
183
184         data = BMO_slot_map_data_get(slot, element);
185         if (data) {
186                 return *(int *)data;
187         }
188         else {
189                 return 0;
190         }
191 }
192
193 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
194 BLI_INLINE bool BMO_slot_map_bool_get(BMOpSlot *slot, const void *element)
195 {
196         void **data;
197         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_BOOL);
198
199         data = BMO_slot_map_data_get(slot, element);
200         if (data) {
201                 return *(bool *)data;
202         }
203         else {
204                 return false;
205         }
206 }
207
208 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
209 BLI_INLINE void *BMO_slot_map_ptr_get(BMOpSlot *slot, const void *element)
210 {
211         void **val = BMO_slot_map_data_get(slot, element);
212         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_INTERNAL);
213         if (val) return *val;
214
215         return NULL;
216 }
217
218 ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
219 BLI_INLINE void *BMO_slot_map_elem_get(BMOpSlot *slot, const void *element)
220 {
221         void **val = (void **) BMO_slot_map_data_get(slot, element);
222         BLI_assert(slot->slot_subtype.map == BMO_OP_SLOT_SUBTYPE_MAP_ELEM);
223         if (val) return *val;
224
225         return NULL;
226 }
227
228 #endif /* __BMESH_OPERATOR_API_INLINE_H__ */