Blender V4.3
bmo_poke.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
13#include "bmesh.hh"
14
15#include "intern/bmesh_operators_private.hh" /* own include */
16
17#include "BLI_math_vector.h"
18
19#include "BKE_customdata.hh"
20
21#define ELE_NEW 1
22
31{
32 const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
33 BMOIter oiter;
34 BMFace *f;
35
36 const float offset = BMO_slot_float_get(op->slots_in, "offset");
37 const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
38 const int center_mode = BMO_slot_int_get(op->slots_in, "center_mode");
39 void (*bm_face_calc_center_fn)(const BMFace *f, float r_cent[3]);
40
41 switch (center_mode) {
43 bm_face_calc_center_fn = BM_face_calc_center_median_weighted;
44 break;
46 bm_face_calc_center_fn = BM_face_calc_center_bounds;
47 break;
49 bm_face_calc_center_fn = BM_face_calc_center_median;
50 break;
51 default:
52 BLI_assert(0);
53 return;
54 }
55
56 BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
57 float f_center[3];
58 BMVert *v_center = nullptr;
59 BMLoop *l_iter, *l_first;
60 /* only interpolate the central loop from the face once,
61 * then copy to all others in the fan */
62 BMLoop *l_center_example;
63
64 /* 1.0 or the average length from the center to the face verts */
65 float offset_fac;
66
67 int i;
68
69 bm_face_calc_center_fn(f, f_center);
70 v_center = BM_vert_create(bm, f_center, nullptr, BM_CREATE_NOP);
72
73 /* handled by BM_loop_interp_from_face */
74 // BM_vert_interp_from_face(bm, v_center, f);
75
76 if (use_relative_offset) {
77 offset_fac = 0.0f;
78 }
79 else {
80 offset_fac = 1.0f;
81 }
82
83 i = 0;
84 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
85 do {
86 BMLoop *l_new;
88 bm, l_iter->v, l_iter->next->v, v_center, nullptr, f, BM_CREATE_NOP);
89 l_new = BM_FACE_FIRST_LOOP(f_new);
90
91 if (i == 0) {
92 l_center_example = l_new->prev;
93 BM_loop_interp_from_face(bm, l_center_example, f, true, false);
94 }
95 else {
96 BM_elem_attrs_copy(bm, l_center_example, l_new->prev);
97 }
98
99 /* Copy Loop Data */
100 BM_elem_attrs_copy(bm, l_iter, l_new);
101 BM_elem_attrs_copy(bm, l_iter->next, l_new->next);
102
104
105 if (cd_loop_mdisp_offset != -1) {
106 float f_new_center[3];
107 BM_face_calc_center_median(f_new, f_new_center);
108 BM_face_interp_multires_ex(bm, f_new, f, f_new_center, f_center, cd_loop_mdisp_offset);
109 }
110
111 if (use_relative_offset) {
112 offset_fac += len_v3v3(f_center, l_iter->v->co);
113 }
114
115 } while ((void)i++, (l_iter = l_iter->next) != l_first);
116
117 if (use_relative_offset) {
118 offset_fac /= float(f->len);
119 }
120 /* else remain at 1.0 */
121
122 copy_v3_v3(v_center->no, f->no);
123 madd_v3_v3fl(v_center->co, v_center->no, offset * offset_fac);
124
125 /* Kill Face */
126 BM_face_kill(bm, f);
127 }
128
131}
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const CustomData *data, eCustomDataType type)
#define BLI_assert(a)
Definition BLI_assert.h:50
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
#define BM_FACE_FIRST_LOOP(p)
void BM_elem_attrs_copy(BMesh *bm, const BMCustomDataCopyMap &map, const BMVert *src, BMVert *dst)
BMFace * BM_face_create_quad_tri(BMesh *bm, BMVert *v1, BMVert *v2, BMVert *v3, BMVert *v4, const BMFace *f_example, const eBMCreateFlag create_flag)
Make Quad/Triangle.
void BM_face_kill(BMesh *bm, BMFace *f)
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:43
@ BM_CREATE_NOP
Definition bmesh_core.hh:24
void BM_face_interp_multires_ex(BMesh *bm, BMFace *f_dst, const BMFace *f_src, const float f_dst_center[3], const float f_src_center[3], const int cd_loop_mdisp_offset)
void BM_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
ATTR_WARN_UNUSED_RESULT BMesh * bm
#define BM_FACE
#define BM_VERT
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_vert_flag_enable(bm, e, oflag)
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)
int BMO_slot_int_get(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)
@ BMOP_POKE_MEDIAN_WEIGHTED
@ BMOP_POKE_BOUNDS
@ BMOP_POKE_MEDIAN
void BM_face_calc_center_bounds(const BMFace *f, float r_cent[3])
void BM_face_calc_center_median(const BMFace *f, float r_cent[3])
void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
#define ELE_NEW
Definition bmo_poke.cc:21
void bmo_poke_exec(BMesh *bm, BMOperator *op)
Definition bmo_poke.cc:30
draw_view in_light_buf[] float
float no[3]
struct BMVert * v
struct BMLoop * prev
struct BMLoop * next
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
float no[3]
CustomData ldata