Blender  V2.93
bmo_poke.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 
25 #include "BLI_math.h"
26 
27 #include "bmesh.h"
28 
29 #include "intern/bmesh_operators_private.h" /* own include */
30 
31 #include "BKE_customdata.h"
32 
33 #define ELE_NEW 1
34 
43 {
44  const int cd_loop_mdisp_offset = CustomData_get_offset(&bm->ldata, CD_MDISPS);
45  BMOIter oiter;
46  BMFace *f;
47 
48  const float offset = BMO_slot_float_get(op->slots_in, "offset");
49  const bool use_relative_offset = BMO_slot_bool_get(op->slots_in, "use_relative_offset");
50  const int center_mode = BMO_slot_int_get(op->slots_in, "center_mode");
51  void (*bm_face_calc_center_fn)(const BMFace *f, float r_cent[3]);
52 
53  switch (center_mode) {
55  bm_face_calc_center_fn = BM_face_calc_center_median_weighted;
56  break;
57  case BMOP_POKE_BOUNDS:
58  bm_face_calc_center_fn = BM_face_calc_center_bounds;
59  break;
60  case BMOP_POKE_MEDIAN:
61  bm_face_calc_center_fn = BM_face_calc_center_median;
62  break;
63  default:
64  BLI_assert(0);
65  return;
66  }
67 
68  BMO_ITER (f, &oiter, op->slots_in, "faces", BM_FACE) {
69  BMFace *f_new;
70  float f_center[3], f_center_mean[3];
71  BMVert *v_center = NULL;
72  BMLoop *l_iter, *l_first;
73  /* only interpolate the central loop from the face once,
74  * then copy to all others in the fan */
75  BMLoop *l_center_example;
76 
77  /* 1.0 or the average length from the center to the face verts */
78  float offset_fac;
79 
80  int i;
81 
82  bm_face_calc_center_fn(f, f_center);
83  v_center = BM_vert_create(bm, f_center, NULL, BM_CREATE_NOP);
84  BMO_vert_flag_enable(bm, v_center, ELE_NEW);
85 
86  if (cd_loop_mdisp_offset != -1) {
87  if (center_mode == BMOP_POKE_MEDIAN) {
88  copy_v3_v3(f_center_mean, f_center);
89  }
90  else {
91  BM_face_calc_center_median(f, f_center_mean);
92  }
93  }
94 
95  /* handled by BM_loop_interp_from_face */
96  // BM_vert_interp_from_face(bm, v_center, f);
97 
98  if (use_relative_offset) {
99  offset_fac = 0.0f;
100  }
101  else {
102  offset_fac = 1.0f;
103  }
104 
105  i = 0;
106  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
107  do {
108  BMLoop *l_new;
109 
110  f_new = BM_face_create_quad_tri(
111  bm, l_iter->v, l_iter->next->v, v_center, NULL, f, BM_CREATE_NOP);
112  l_new = BM_FACE_FIRST_LOOP(f_new);
113 
114  if (i == 0) {
115  l_center_example = l_new->prev;
116  BM_loop_interp_from_face(bm, l_center_example, f, true, false);
117  }
118  else {
119  BM_elem_attrs_copy(bm, bm, l_center_example, l_new->prev);
120  }
121 
122  /* Copy Loop Data */
123  BM_elem_attrs_copy(bm, bm, l_iter, l_new);
124  BM_elem_attrs_copy(bm, bm, l_iter->next, l_new->next);
125 
127 
128  if (cd_loop_mdisp_offset != -1) {
129  float f_new_center[3];
130  BM_face_calc_center_median(f_new, f_new_center);
131  BM_face_interp_multires_ex(bm, f_new, f, f_new_center, f_center, cd_loop_mdisp_offset);
132  }
133 
134  if (use_relative_offset) {
135  offset_fac += len_v3v3(f_center, l_iter->v->co);
136  }
137 
138  } while ((void)i++, (l_iter = l_iter->next) != l_first);
139 
140  if (use_relative_offset) {
141  offset_fac /= (float)f->len;
142  }
143  /* else remain at 1.0 */
144 
145  copy_v3_v3(v_center->no, f->no);
146  madd_v3_v3fl(v_center->co, v_center->no, offset * offset_fac);
147 
148  /* Kill Face */
149  BM_face_kill(bm, f);
150  }
151 
154 }
typedef float(TangentPoint)[2]
CustomData interface, see also DNA_customdata_types.h.
int CustomData_get_offset(const struct CustomData *data, int type)
#define BLI_assert(a)
Definition: BLI_assert.h:58
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])
@ BM_FACE
Definition: bmesh_class.h:386
@ BM_VERT
Definition: bmesh_class.h:383
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
void BM_elem_attrs_copy(BMesh *bm_src, BMesh *bm_dst, const void *ele_src, void *ele_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.
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.c:58
void BM_face_kill(BMesh *bm, BMFace *f)
Definition: bmesh_core.c:881
@ BM_CREATE_NOP
Definition: bmesh_core.h:27
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)
Definition: bmesh_interp.c:591
void BM_loop_interp_from_face(BMesh *bm, BMLoop *l_dst, const BMFace *f_src, const bool do_vertex, const bool do_multires)
Definition: bmesh_interp.c:737
ATTR_WARN_UNUSED_RESULT BMesh * bm
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_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)
void BMO_slot_buffer_from_enabled_flag(BMesh *bm, BMOperator *op, BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name, const char htype, const short oflag)
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.c:33
void bmo_poke_exec(BMesh *bm, BMOperator *op)
Definition: bmo_poke.c:42
int len
Definition: bmesh_class.h:279
float no[3]
Definition: bmesh_class.h:280
struct BMVert * v
Definition: bmesh_class.h:165
struct BMLoop * prev
Definition: bmesh_class.h:245
struct BMLoop * next
Definition: bmesh_class.h:245
struct BMOpSlot slots_out[BMO_OP_MAX_SLOTS]
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:99
float no[3]
Definition: bmesh_class.h:100
CustomData ldata
Definition: bmesh_class.h:337