Blender  V3.3
bmo_planar_faces.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 
9 #include "MEM_guardedalloc.h"
10 
11 #include "BLI_ghash.h"
12 #include "BLI_math.h"
13 
14 #include "bmesh.h"
15 
16 #include "intern/bmesh_operators_private.h" /* own include */
17 
18 #define ELE_VERT_ADJUST (1 << 0)
19 #define ELE_FACE_ADJUST (1 << 1)
20 
21 struct VertAccum {
22  float co[3];
23  int co_tot;
24 };
25 
27 {
28  const float fac = BMO_slot_float_get(op->slots_in, "factor");
29  const int iterations = BMO_slot_int_get(op->slots_in, "iterations");
30  const int faces_num = BMO_slot_buffer_len(op->slots_in, "faces");
31 
32  const float eps = 0.00001f;
33  const float eps_sq = square_f(eps);
34 
35  BMOIter oiter;
36  BMFace *f;
37  BLI_mempool *vert_accum_pool;
38  GHash *vaccum_map;
39  float(*faces_center)[3];
40  int i, iter_step, shared_vert_num;
41 
42  faces_center = MEM_mallocN(sizeof(*faces_center) * faces_num, __func__);
43 
44  shared_vert_num = 0;
45  BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
46  BMLoop *l_iter, *l_first;
47 
48  if (f->len == 3) {
49  continue;
50  }
51 
52  BM_face_calc_center_median_weighted(f, faces_center[i]);
53 
54  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
55  do {
56  if (!BMO_vert_flag_test(bm, l_iter->v, ELE_VERT_ADJUST)) {
58  shared_vert_num += 1;
59  }
60  } while ((l_iter = l_iter->next) != l_first);
61 
63  }
64 
65  vert_accum_pool = BLI_mempool_create(sizeof(struct VertAccum), 0, 512, BLI_MEMPOOL_NOP);
66  vaccum_map = BLI_ghash_ptr_new_ex(__func__, shared_vert_num);
67 
68  for (iter_step = 0; iter_step < iterations; iter_step++) {
69  GHashIterator gh_iter;
70  bool changed = false;
71 
72  BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
73  BMLoop *l_iter, *l_first;
74  float plane[4];
75 
77  continue;
78  }
80 
81  BLI_assert(f->len != 3);
82 
83  /* keep original face data (else we 'move' the face) */
84 #if 0
87 #endif
88 
89  plane_from_point_normal_v3(plane, faces_center[i], f->no);
90 
91  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
92  do {
93  struct VertAccum *va;
94  void **va_p;
95  float co[3];
96 
97  if (!BLI_ghash_ensure_p(vaccum_map, l_iter->v, &va_p)) {
98  *va_p = BLI_mempool_calloc(vert_accum_pool);
99  }
100  va = *va_p;
101 
102  closest_to_plane_normalized_v3(co, plane, l_iter->v->co);
103  va->co_tot += 1;
104 
105  interp_v3_v3v3(va->co, va->co, co, 1.0f / (float)va->co_tot);
106  } while ((l_iter = l_iter->next) != l_first);
107  }
108 
109  GHASH_ITER (gh_iter, vaccum_map) {
110  BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
111  struct VertAccum *va = BLI_ghashIterator_getValue(&gh_iter);
112  BMIter iter;
113 
114  if (len_squared_v3v3(v->co, va->co) > eps_sq) {
116  interp_v3_v3v3(v->co, v->co, va->co, fac);
117  changed = true;
118  }
119 
120  /* tag for re-calculation */
121  BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
122  if (f->len != 3) {
124  }
125  }
126  }
127 
128  /* if nothing changed, break out early */
129  if (changed == false) {
130  break;
131  }
132 
133  BLI_ghash_clear(vaccum_map, NULL, NULL);
134  BLI_mempool_clear(vert_accum_pool);
135  }
136 
137  MEM_freeN(faces_center);
138  BLI_ghash_free(vaccum_map, NULL, NULL);
139  BLI_mempool_destroy(vert_accum_pool);
140 }
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:46
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:298
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:858
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:302
#define GHASH_ITER(gh_iter_, ghash_)
Definition: BLI_ghash.h:321
GHash * BLI_ghash_ptr_new_ex(const char *info, unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:863
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:755
MINLINE float square_f(float a)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
Definition: math_geom.c:209
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:408
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], float t)
Definition: math_vector.c:29
@ BLI_MEMPOOL_NOP
Definition: BLI_mempool.h:99
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int elem_num, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL
Definition: BLI_mempool.c:253
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:707
void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:702
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
Definition: BLI_mempool.c:347
Read Guarded memory(de)allocation.
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:622
@ BM_FACE
Definition: bmesh_class.h:386
#define BM_ITER_ELEM(ele, iter, data, itype)
@ BM_FACES_OF_VERT
ATTR_WARN_UNUSED_RESULT BMesh * bm
#define BMO_ITER_INDEX(ele, iter, slot_args, slot_name, restrict_flag, i_)
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_vert_flag_test(bm, e, oflag)
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)
#define BMO_face_flag_disable(bm, e, oflag)
#define BMO_face_flag_test(bm, e, oflag)
void BM_face_normal_update(BMFace *f)
void BM_face_calc_center_median_weighted(const BMFace *f, float r_cent[3])
ATTR_WARN_UNUSED_RESULT const BMVert * v
#define ELE_FACE_ADJUST
#define ELE_VERT_ADJUST
void bmo_planar_faces_exec(BMesh *bm, BMOperator *op)
void(* MEM_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:33
const btScalar eps
Definition: poly34.cpp:11
int len
Definition: bmesh_class.h:267
float no[3]
Definition: bmesh_class.h:271
struct BMVert * v
Definition: bmesh_class.h:153
struct BMLoop * next
Definition: bmesh_class.h:233
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:87
float co[3]