Blender V5.0
bmo_utils.cc
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
11
12#include "MEM_guardedalloc.h"
13
14#include "DNA_mesh_types.h"
15#include "DNA_meshdata_types.h"
16
17#include "BLI_alloca.h"
18#include "BLI_math_matrix.h"
19#include "BLI_math_vector.h"
20
21#include "BKE_attribute.h"
22#include "BKE_customdata.hh"
23
24#include "bmesh.hh"
25
26#include "intern/bmesh_operators_private.hh" /* own include */
27
28#define ELE_NEW 1
29
31{
32 float vec[3];
33
34 BMO_slot_vec_get(op->slots_in, "co", vec);
35
38}
39
41{
42 BMOIter iter;
43 BMVert *v;
44 float mat[4][4], mat_space[4][4], imat_space[4][4];
45
46 const uint shape_keys_len = BMO_slot_bool_get(op->slots_in, "use_shapekey") ?
48 0;
49 const uint cd_shape_key_offset = CustomData_get_offset(&bm->vdata, CD_SHAPEKEY);
50
51 BMO_slot_mat4_get(op->slots_in, "matrix", mat);
52 BMO_slot_mat4_get(op->slots_in, "space", mat_space);
53
54 if (!is_zero_m4(mat_space)) {
55 invert_m4_m4(imat_space, mat_space);
56 mul_m4_series(mat, imat_space, mat, mat_space);
57 }
58
59 BMO_ITER (v, &iter, op->slots_in, "verts", BM_VERT) {
60 mul_m4_v3(mat, v->co);
61
62 if (shape_keys_len != 0) {
63 float (*co_dst)[3] = static_cast<float (*)[3]>(
64 BM_ELEM_CD_GET_VOID_P(v, cd_shape_key_offset));
65 for (int i = 0; i < shape_keys_len; i++, co_dst++) {
66 mul_m4_v3(mat, *co_dst);
67 }
68 }
69 }
70}
71
73{
74 float mat[4][4], vec[3];
75
76 BMO_slot_vec_get(op->slots_in, "vec", vec);
77
78 unit_m4(mat);
79 copy_v3_v3(mat[3], vec);
80
82 op->flag,
83 "transform matrix=%m4 space=%s verts=%s use_shapekey=%s",
84 mat,
85 op,
86 "space",
87 op,
88 "verts",
89 op,
90 "use_shapekey");
91}
92
94{
95 float mat[3][3], vec[3];
96
97 BMO_slot_vec_get(op->slots_in, "vec", vec);
98
99 unit_m3(mat);
100 mat[0][0] = vec[0];
101 mat[1][1] = vec[1];
102 mat[2][2] = vec[2];
103
105 op->flag,
106 "transform matrix=%m3 space=%s verts=%s use_shapekey=%s",
107 mat,
108 op,
109 "space",
110 op,
111 "verts",
112 op,
113 "use_shapekey");
114}
115
117{
118 float center[3];
119 float mat[4][4];
120
121 BMO_slot_vec_get(op->slots_in, "cent", center);
122 BMO_slot_mat4_get(op->slots_in, "matrix", mat);
123 transform_pivot_set_m4(mat, center);
124
126 op->flag,
127 "transform matrix=%m4 space=%s verts=%s use_shapekey=%s",
128 mat,
129 op,
130 "space",
131 op,
132 "verts",
133 op,
134 "use_shapekey");
135}
136
138{
139 const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
140 const bool use_loop_mdisp_flip = BMO_slot_bool_get(op->slots_in, "flip_multires");
141 BMOIter siter;
142 BMFace *f;
143
144 BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
145 BM_face_normal_flip_ex(bm, f, cd_loop_mdisp_offset, use_loop_mdisp_flip);
146 }
147}
148
149#define SEL_FLAG 1
150#define SEL_ORIG 2
151
153{
154 BMOIter siter;
155 BMFace *f;
156 bool changed = false;
157 BMO_ITER (f, &siter, op->slots_in, "faces", BM_FACE) {
158 if (f->len == 4) {
159 f->l_first = f->l_first->next;
160 changed = true;
161 }
162 }
163 if (changed) {
164 bm->elem_index_dirty |= BM_LOOP;
165 }
166}
167
168static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, const bool value)
169{
170 BMLoop *l_iter;
171 BMLoop *l_first;
172
173 BMO_face_flag_set(bm, f, oflag, value);
174 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
175 do {
176 BMO_edge_flag_set(bm, l_iter->e, oflag, value);
177 BMO_vert_flag_set(bm, l_iter->v, oflag, value);
178 } while ((l_iter = l_iter->next) != l_first);
179}
180
182 BMOperator *op,
183 const bool use_faces,
184 const bool use_faces_step)
185{
186 BMOIter siter;
187
188 if (!use_faces) {
189 BMVert *v;
190
191 BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
192 bool found = false;
193
194 {
195 BMIter eiter;
196 BMEdge *e;
197
198 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
200 found = true;
201 break;
202 }
203 }
204 }
205
206 if (found) {
207 if (!use_faces_step) {
208 BMIter eiter;
209 BMEdge *e;
210
211 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
215 }
216 }
217 }
218 else {
219 BMIter fiter;
220 BMFace *f;
221
222 BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
225 }
226 }
227
228 /* handle wire edges (when stepping over faces) */
229 {
230 BMIter eiter;
231 BMEdge *e;
232 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
233 if (BM_edge_is_wire(e)) {
235 {
238 }
239 }
240 }
241 }
242 }
243 }
244 }
245 }
246 else {
247 BMFace *f;
248
249 BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
250 BMIter liter;
251 BMLoop *l;
252
253 BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
254 if (!use_faces_step) {
255 BMIter fiter;
256 BMFace *f_other;
257
258 BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) {
259 if (!BMO_face_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG) &&
261 {
263 }
264 }
265 }
266 else {
267 BMIter fiter;
268 BMFace *f_other;
269
270 BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) {
271 if (!BMO_face_flag_test(bm, f_other, SEL_ORIG | SEL_FLAG) &&
273 {
275 }
276 }
277 }
278 }
279 }
280 }
281}
282
284 BMOperator *op,
285 const bool use_faces,
286 const bool use_faces_step)
287{
288 BMOIter siter;
289
290 if (!use_faces) {
291 BMVert *v;
292
293 BMO_ITER (v, &siter, op->slots_in, "geom", BM_VERT) {
294 bool found = false;
295
296 if (!use_faces_step) {
297 BMIter eiter;
298 BMEdge *e;
299
300 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
302 found = true;
303 break;
304 }
305 }
306 }
307 else {
308 BMIter fiter;
309 BMFace *f;
310
311 BM_ITER_ELEM (f, &fiter, v, BM_FACES_OF_VERT) {
312 if (!BMO_face_flag_test(bm, f, SEL_ORIG)) {
313 found = true;
314 break;
315 }
316 }
317
318 /* handle wire edges (when stepping over faces) */
319 if (!found) {
320 BMIter eiter;
321 BMEdge *e;
322
323 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
324 if (BM_edge_is_wire(e)) {
326 found = true;
327 break;
328 }
329 }
330 }
331 }
332 }
333
334 if (found) {
335 BMIter eiter;
336 BMEdge *e;
337
339
340 BM_ITER_ELEM (e, &eiter, v, BM_EDGES_OF_VERT) {
342 }
343 }
344 }
345 }
346 else {
347 BMFace *f;
348
349 BMO_ITER (f, &siter, op->slots_in, "geom", BM_FACE) {
350 BMIter liter;
351 BMLoop *l;
352
353 BM_ITER_ELEM (l, &liter, f, BM_LOOPS_OF_FACE) {
354
355 if (!use_faces_step) {
356 BMIter fiter;
357 BMFace *f_other;
358
359 BM_ITER_ELEM (f_other, &fiter, l->e, BM_FACES_OF_EDGE) {
360 if (!BMO_face_flag_test(bm, f_other, SEL_ORIG)) {
362 break;
363 }
364 }
365 }
366 else {
367 BMIter fiter;
368 BMFace *f_other;
369
370 BM_ITER_ELEM (f_other, &fiter, l->v, BM_FACES_OF_VERT) {
371 if (!BMO_face_flag_test(bm, f_other, SEL_ORIG)) {
373 break;
374 }
375 }
376 }
377 }
378 }
379 }
380}
381
383{
384 const bool use_faces = BMO_slot_bool_get(op->slots_in, "use_faces");
385 const bool use_face_step = BMO_slot_bool_get(op->slots_in, "use_face_step");
386 const bool constrict = BMO_slot_bool_get(op->slots_in, "use_contract");
387
389
390 if (constrict) {
391 bmo_region_extend_contract(bm, op, use_faces, use_face_step);
392 }
393 else {
394 bmo_region_extend_expand(bm, op, use_faces, use_face_step);
395 }
396
398}
399
401{
402 BMOIter siter;
403 BMIter iter;
404 BMVert *v;
405 BMEdge *e;
406 float (*cos)[3] = static_cast<float (*)[3]>(
407 MEM_mallocN(sizeof(*cos) * BMO_slot_buffer_len(op->slots_in, "verts"), __func__));
408 float *co, *co2, clip_dist = BMO_slot_float_get(op->slots_in, "clip_dist");
409 const float fac = BMO_slot_float_get(op->slots_in, "factor");
410 int i, j, clipx, clipy, clipz;
411 int xaxis, yaxis, zaxis;
412
413 clipx = BMO_slot_bool_get(op->slots_in, "mirror_clip_x");
414 clipy = BMO_slot_bool_get(op->slots_in, "mirror_clip_y");
415 clipz = BMO_slot_bool_get(op->slots_in, "mirror_clip_z");
416
417 xaxis = BMO_slot_bool_get(op->slots_in, "use_axis_x");
418 yaxis = BMO_slot_bool_get(op->slots_in, "use_axis_y");
419 zaxis = BMO_slot_bool_get(op->slots_in, "use_axis_z");
420
421 i = 0;
422 BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
423
424 co = cos[i];
425 zero_v3(co);
426
427 j = 0;
428 BM_ITER_ELEM (e, &iter, v, BM_EDGES_OF_VERT) {
429 co2 = BM_edge_other_vert(e, v)->co;
430 add_v3_v3v3(co, co, co2);
431 j += 1;
432 }
433
434 if (!j) {
435 copy_v3_v3(co, v->co);
436 i++;
437 continue;
438 }
439
440 mul_v3_fl(co, 1.0f / float(j));
441 interp_v3_v3v3(co, v->co, co, fac);
442
443 if (clipx && fabsf(v->co[0]) <= clip_dist) {
444 co[0] = 0.0f;
445 }
446 if (clipy && fabsf(v->co[1]) <= clip_dist) {
447 co[1] = 0.0f;
448 }
449 if (clipz && fabsf(v->co[2]) <= clip_dist) {
450 co[2] = 0.0f;
451 }
452
453 i++;
454 }
455
456 i = 0;
457 BMO_ITER (v, &siter, op->slots_in, "verts", BM_VERT) {
458 if (xaxis) {
459 v->co[0] = cos[i][0];
460 }
461 if (yaxis) {
462 v->co[1] = cos[i][1];
463 }
464 if (zaxis) {
465 v->co[2] = cos[i][2];
466 }
467
468 i++;
469 }
470
471 MEM_freeN(cos);
472}
473
474/**************************************************************************** *
475 * Cycle UVs for a face
476 **************************************************************************** */
477
479{
480 BMOIter fs_iter; /* selected faces iterator */
481 BMFace *fs; /* current face */
482 BMIter l_iter; /* iteration loop */
483
484 const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
485 const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
486
487 if (cd_loop_uv_offset != -1) {
488 BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
489 if (use_ccw == false) { /* same loops direction */
490 BMLoop *lf; /* current face loops */
491 float *f_luv; /* first face loop uv */
492 float p_uv[2]; /* previous uvs */
493 float t_uv[2]; /* temp uvs */
494
495 int n = 0;
496 BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
497 /* current loop uv is the previous loop uv */
498 float *luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset);
499 if (n == 0) {
500 f_luv = luv;
501 copy_v2_v2(p_uv, luv);
502 }
503 else {
504 copy_v2_v2(t_uv, luv);
505 copy_v2_v2(luv, p_uv);
506 copy_v2_v2(p_uv, t_uv);
507 }
508 n++;
509 }
510
511 copy_v2_v2(f_luv, p_uv);
512 }
513 else { /* counter loop direction */
514 BMLoop *lf; /* current face loops */
515 float *p_luv; /* previous loop uv */
516 float *luv;
517 float t_uv[2]; /* current uvs */
518
519 int n = 0;
520 BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
521 /* previous loop uv is the current loop uv */
522 luv = BM_ELEM_CD_GET_FLOAT_P(lf, cd_loop_uv_offset);
523 if (n == 0) {
524 p_luv = luv;
525 copy_v2_v2(t_uv, luv);
526 }
527 else {
528 copy_v2_v2(p_luv, luv);
529 p_luv = luv;
530 }
531 n++;
532 }
533
534 copy_v2_v2(luv, t_uv);
535 }
536 }
537 }
538}
539
540/**************************************************************************** *
541 * Reverse UVs for a face
542 **************************************************************************** */
543
544static void bm_face_reverse_uvs(BMFace *f, const int cd_loop_uv_offset)
545{
546 BMIter iter;
547 BMLoop *l;
548 int i;
549
550 float (*uvs)[2] = BLI_array_alloca(uvs, f->len);
551
552 BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
553 float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
554 copy_v2_v2(uvs[i], luv);
555 }
556
557 /* now that we have the uvs in the array, reverse! */
558 BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
559 /* current loop uv is the previous loop uv */
560 float *luv = BM_ELEM_CD_GET_FLOAT_P(l, cd_loop_uv_offset);
561 copy_v2_v2(luv, uvs[(f->len - i - 1)]);
562 }
563}
565{
566 BMOIter iter;
567 BMFace *f;
568 const int cd_loop_uv_offset = CustomData_get_offset(&bm->ldata, CD_PROP_FLOAT2);
569
570 if (cd_loop_uv_offset != -1) {
571 BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {
572 bm_face_reverse_uvs(f, cd_loop_uv_offset);
573 }
574 }
575}
576
577/**************************************************************************** *
578 * Cycle colors for a face
579 **************************************************************************** */
580
582 int index,
583 int *r_cd_color_offset,
584 std::optional<eCustomDataType> *r_cd_color_type)
585{
586 int color_index = 0;
587 for (const CustomDataLayer &layer : blender::Span(bm->ldata.layers, bm->ldata.totlayer)) {
589 if (color_index == index) {
590 *r_cd_color_offset = layer.offset;
591 *r_cd_color_type = eCustomDataType(layer.type);
592 return;
593 }
594 color_index++;
595 }
596 }
597 *r_cd_color_offset = -1;
598}
599
601{
602 BMOIter fs_iter; /* selected faces iterator */
603 BMFace *fs; /* current face */
604 BMIter l_iter; /* iteration loop */
605
606 const bool use_ccw = BMO_slot_bool_get(op->slots_in, "use_ccw");
607
608 const int color_index = BMO_slot_int_get(op->slots_in, "color_index");
609
610 int cd_loop_color_offset;
611 std::optional<eCustomDataType> cd_loop_color_type;
612 bmo_get_loop_color_ref(bm, color_index, &cd_loop_color_offset, &cd_loop_color_type);
613
614 if (cd_loop_color_offset == -1) {
615 BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "color_index is invalid");
616 return;
617 }
618
619 const size_t size = cd_loop_color_type == CD_PROP_COLOR ? sizeof(MPropCol) : sizeof(MLoopCol);
620 void *p_col; /* previous color */
621 void *t_col = alloca(size); /* Temp color. */
622
623 BMO_ITER (fs, &fs_iter, op->slots_in, "faces", BM_FACE) {
624 if (use_ccw == false) { /* same loops direction */
625 BMLoop *lf; /* current face loops */
626 void *f_lcol; /* first face loop color */
627
628 int n = 0;
629 BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
630 /* current loop color is the previous loop color */
631 void *lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
632
633 if (n == 0) {
634 f_lcol = lcol;
635 p_col = lcol;
636 }
637 else {
638 memcpy(t_col, lcol, size);
639 memcpy(lcol, p_col, size);
640 memcpy(p_col, t_col, size);
641 }
642 n++;
643 }
644
645 memcpy(f_lcol, p_col, size);
646 }
647 else { /* counter loop direction */
648 BMLoop *lf; /* current face loops */
649 void *lcol, *p_lcol;
650
651 int n = 0;
652 BM_ITER_ELEM (lf, &l_iter, fs, BM_LOOPS_OF_FACE) {
653 /* previous loop color is the current loop color */
654 lcol = BM_ELEM_CD_GET_VOID_P(lf, cd_loop_color_offset);
655 if (n == 0) {
656 p_lcol = lcol;
657 memcpy(t_col, lcol, size);
658 }
659 else {
660 memcpy(p_lcol, lcol, size);
661 p_lcol = lcol;
662 }
663 n++;
664 }
665
666 memcpy(lcol, t_col, size);
667 }
668 }
669}
670
671/*************************************************************************** *
672 * Reverse colors for a face
673 *************************************************************************** */
675 const int cd_loop_color_offset,
676 const eCustomDataType cd_loop_color_type)
677{
678 BMIter iter;
679 BMLoop *l;
680 int i;
681
682 const size_t size = cd_loop_color_type == CD_PROP_COLOR ? sizeof(MPropCol) : sizeof(MLoopCol);
683
684 char *cols = static_cast<char *>(alloca(size * f->len));
685
686 char *col = cols;
687 BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
688 void *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
689 memcpy((void *)col, lcol, size);
690 col += size;
691 }
692
693 /* now that we have the uvs in the array, reverse! */
694 BM_ITER_ELEM_INDEX (l, &iter, f, BM_LOOPS_OF_FACE, i) {
695 /* current loop uv is the previous loop color */
696 void *lcol = BM_ELEM_CD_GET_VOID_P(l, cd_loop_color_offset);
697
698 col = cols + (f->len - i - 1) * size;
699 memcpy(lcol, (void *)col, size);
700 }
701}
702
704{
705 BMOIter iter;
706 BMFace *f;
707
708 const int color_index = BMO_slot_int_get(op->slots_in, "color_index");
709
710 int cd_loop_color_offset;
711 std::optional<eCustomDataType> cd_loop_color_type;
712 bmo_get_loop_color_ref(bm, color_index, &cd_loop_color_offset, &cd_loop_color_type);
713
714 if (cd_loop_color_offset == -1) {
715 BMO_error_raise(bm, op, BMO_ERROR_CANCEL, "color_index is invalid");
716 return;
717 }
718
719 BMO_ITER (f, &iter, op->slots_in, "faces", BM_FACE) {
720 bm_face_reverse_colors(f, cd_loop_color_offset, *cd_loop_color_type);
721 }
722}
Generic geometry attributes built on CustomData.
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
eCustomDataMask CD_TYPE_AS_MASK(eCustomDataType type)
int CustomData_number_of_layers(const CustomData *data, eCustomDataType type)
#define BLI_array_alloca(arr, realsize)
Definition BLI_alloca.h:18
void unit_m3(float m[3][3])
void transform_pivot_set_m4(float mat[4][4], const float pivot[3])
void mul_m4_v3(const float M[4][4], float r[3])
#define mul_m4_series(...)
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
bool is_zero_m4(const float mat[4][4])
void unit_m4(float m[4][4])
MINLINE void copy_v2_v2(float r[2], const float a[2])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
unsigned int uint
#define CD_MASK_COLOR_ALL
@ CD_PROP_COLOR
@ CD_PROP_FLOAT2
Read Guarded memory(de)allocation.
#define BM_ALL_NOLOOP
#define BM_FACE_FIRST_LOOP(p)
#define BM_ELEM_CD_GET_FLOAT_P(ele, offset)
@ BM_ELEM_HIDDEN
@ BM_LOOP
#define BM_ELEM_CD_GET_VOID_P(ele, offset)
BMVert * BM_vert_create(BMesh *bm, const float co[3], const BMVert *v_example, const eBMCreateFlag create_flag)
Main function for creating a new vertex.
Definition bmesh_core.cc:41
@ BM_CREATE_NOP
Definition bmesh_core.hh:28
@ BMO_ERROR_CANCEL
void BMO_error_raise(BMesh *bm, BMOperator *owner, eBMOpErrorLevel level, const char *msg) ATTR_NONNULL(1
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
@ BM_FACES_OF_EDGE
@ BM_FACES_OF_VERT
@ BM_EDGES_OF_VERT
@ BM_LOOPS_OF_FACE
#define BM_ITER_ELEM_INDEX(ele, iter, data, itype, indexvar)
BMesh * bm
#define BM_FACE
#define BM_VERT
void BMO_slot_mat4_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_mat[4][4])
void BMO_slot_buffer_flag_enable(BMesh *bm, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
BMO_FLAG_BUFFER.
#define BMO_edge_flag_test(bm, e, oflag)
void BMO_slot_vec_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, float r_vec[3])
#define BMO_edge_flag_enable(bm, e, oflag)
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_vert_flag_enable(bm, e, oflag)
#define BMO_vert_flag_set(bm, e, oflag, val)
#define BMO_edge_flag_set(bm, e, oflag, val)
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, char htype, short oflag)
#define BMO_face_flag_enable(bm, e, oflag)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
#define BMO_face_flag_set(bm, e, oflag, val)
int BMO_slot_int_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
int BMO_slot_buffer_len(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
bool BMO_op_callf(BMesh *bm, int flag, const char *fmt,...)
#define BMO_face_flag_test(bm, e, oflag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
ATTR_WARN_UNUSED_RESULT const BMFlagLayer const short oflag
void BM_face_normal_flip_ex(BMesh *bm, BMFace *f, const int cd_loop_mdisp_offset, const bool use_loop_mdisp_flip)
Face Flip Normal.
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
BLI_INLINE bool BM_edge_is_wire(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define ELE_NEW
void bmo_rotate_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:116
void bmo_region_extend_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:382
void bmo_reverse_uvs_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:564
#define SEL_ORIG
Definition bmo_utils.cc:150
void bmo_flip_quad_tessellation_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:152
static void bmo_region_extend_expand(BMesh *bm, BMOperator *op, const bool use_faces, const bool use_faces_step)
Definition bmo_utils.cc:181
void bmo_transform_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:40
static void bmo_face_flag_set_flush(BMesh *bm, BMFace *f, const short oflag, const bool value)
Definition bmo_utils.cc:168
void bmo_reverse_colors_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:703
static void bmo_get_loop_color_ref(BMesh *bm, int index, int *r_cd_color_offset, std::optional< eCustomDataType > *r_cd_color_type)
Definition bmo_utils.cc:581
void bmo_rotate_colors_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:600
static void bm_face_reverse_uvs(BMFace *f, const int cd_loop_uv_offset)
Definition bmo_utils.cc:544
void bmo_rotate_uvs_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:478
#define SEL_FLAG
Definition bmo_utils.cc:149
void bmo_translate_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:72
void bmo_create_vert_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:30
void bmo_smooth_vert_exec(BMesh *, BMOperator *op)
Definition bmo_utils.cc:400
void bmo_scale_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:93
static void bmo_region_extend_contract(BMesh *bm, BMOperator *op, const bool use_faces, const bool use_faces_step)
Definition bmo_utils.cc:283
static void bm_face_reverse_colors(BMFace *f, const int cd_loop_color_offset, const eCustomDataType cd_loop_color_type)
Definition bmo_utils.cc:674
void bmo_reverse_faces_exec(BMesh *bm, BMOperator *op)
Definition bmo_utils.cc:137
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
Definition btDbvt.cpp:52
nullptr float
uint col
#define cos
void * MEM_mallocN(size_t len, const char *str)
Definition mallocn.cc:128
void MEM_freeN(void *vmemh)
Definition mallocn.cc:113
#define fabsf
BMLoop * l_first
struct BMVert * v
struct BMEdge * e
struct BMLoop * next
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
i
Definition text_draw.cc:230