Blender V4.3
bmo_planar_faces.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#include "MEM_guardedalloc.h"
12
13#include "BLI_ghash.h"
14#include "BLI_math_geom.h"
15#include "BLI_math_vector.h"
16
17#include "bmesh.hh"
18
19#include "intern/bmesh_operators_private.hh" /* own include */
20
21#define ELE_VERT_ADJUST (1 << 0)
22#define ELE_FACE_ADJUST (1 << 1)
23
24struct VertAccum {
25 float co[3];
26 int co_tot;
27};
28
30{
31 const float fac = BMO_slot_float_get(op->slots_in, "factor");
32 const int iterations = BMO_slot_int_get(op->slots_in, "iterations");
33 const int faces_num = BMO_slot_buffer_len(op->slots_in, "faces");
34
35 const float eps = 0.00001f;
36 const float eps_sq = square_f(eps);
37
38 BMOIter oiter;
39 BMFace *f;
40 BLI_mempool *vert_accum_pool;
41 GHash *vaccum_map;
42 float(*faces_center)[3];
43 int i, iter_step, shared_vert_num;
44
45 faces_center = static_cast<float(*)[3]>(
46 MEM_mallocN(sizeof(*faces_center) * faces_num, __func__));
47
48 shared_vert_num = 0;
49 BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
50 BMLoop *l_iter, *l_first;
51
52 if (f->len == 3) {
53 continue;
54 }
55
56 BM_face_calc_center_median_weighted(f, faces_center[i]);
57
58 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
59 do {
60 if (!BMO_vert_flag_test(bm, l_iter->v, ELE_VERT_ADJUST)) {
62 shared_vert_num += 1;
63 }
64 } while ((l_iter = l_iter->next) != l_first);
65
67 }
68
69 vert_accum_pool = BLI_mempool_create(sizeof(VertAccum), 0, 512, BLI_MEMPOOL_NOP);
70 vaccum_map = BLI_ghash_ptr_new_ex(__func__, shared_vert_num);
71
72 for (iter_step = 0; iter_step < iterations; iter_step++) {
73 GHashIterator gh_iter;
74 bool changed = false;
75
76 BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
77 BMLoop *l_iter, *l_first;
78 float plane[4];
79
81 continue;
82 }
84
85 BLI_assert(f->len != 3);
86
87/* keep original face data (else we 'move' the face) */
88#if 0
91#endif
92
93 plane_from_point_normal_v3(plane, faces_center[i], f->no);
94
95 l_iter = l_first = BM_FACE_FIRST_LOOP(f);
96 do {
97 VertAccum *va;
98 void **va_p;
99 float co[3];
100
101 if (!BLI_ghash_ensure_p(vaccum_map, l_iter->v, &va_p)) {
102 *va_p = BLI_mempool_calloc(vert_accum_pool);
103 }
104 va = static_cast<VertAccum *>(*va_p);
105
106 closest_to_plane_normalized_v3(co, plane, l_iter->v->co);
107 va->co_tot += 1;
108
109 interp_v3_v3v3(va->co, va->co, co, 1.0f / float(va->co_tot));
110 } while ((l_iter = l_iter->next) != l_first);
111 }
112
113 GHASH_ITER (gh_iter, vaccum_map) {
114 BMVert *v = static_cast<BMVert *>(BLI_ghashIterator_getKey(&gh_iter));
115 VertAccum *va = static_cast<VertAccum *>(BLI_ghashIterator_getValue(&gh_iter));
116 BMIter iter;
117
118 if (len_squared_v3v3(v->co, va->co) > eps_sq) {
120 interp_v3_v3v3(v->co, v->co, va->co, fac);
121 changed = true;
122 }
123
124 /* tag for re-calculation */
125 BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
126 if (f->len != 3) {
128 }
129 }
130 }
131
132 /* if nothing changed, break out early */
133 if (changed == false) {
134 break;
135 }
136
137 BLI_ghash_clear(vaccum_map, nullptr, nullptr);
138 BLI_mempool_clear(vert_accum_pool);
139 }
140
141 MEM_freeN(faces_center);
142 BLI_ghash_free(vaccum_map, nullptr, nullptr);
143 BLI_mempool_destroy(vert_accum_pool);
144}
#define BLI_assert(a)
Definition BLI_assert.h:50
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.h:299
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition BLI_ghash.c:855
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.h:303
#define GHASH_ITER(gh_iter_, ghash_)
Definition BLI_ghash.h:322
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:860
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition BLI_ghash.c:752
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.cc:215
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition math_geom.cc:440
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:36
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
@ BLI_MEMPOOL_NOP
Definition BLI_mempool.h:86
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_RETURNS_NONNULL ATTR_NONNULL(1)
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1)
Read Guarded memory(de)allocation.
#define BM_FACE_FIRST_LOOP(p)
#define BM_ITER_ELEM(ele, iter, data, itype)
@ BM_FACES_OF_VERT
ATTR_WARN_UNUSED_RESULT BMesh * bm
#define BM_FACE
#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)
draw_view in_light_buf[] float
void *(* MEM_mallocN)(size_t len, const char *str)
Definition mallocn.cc:44
void MEM_freeN(void *vmemh)
Definition mallocn.cc:105
const btScalar eps
Definition poly34.cpp:11
float no[3]
struct BMVert * v
struct BMLoop * next
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]