Blender  V2.93
bmo_planar_faces.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 
23 #include "MEM_guardedalloc.h"
24 
25 #include "BLI_ghash.h"
26 #include "BLI_math.h"
27 
28 #include "bmesh.h"
29 
30 #include "intern/bmesh_operators_private.h" /* own include */
31 
32 #define ELE_VERT_ADJUST (1 << 0)
33 #define ELE_FACE_ADJUST (1 << 1)
34 
35 struct VertAccum {
36  float co[3];
37  int co_tot;
38 };
39 
41 {
42  const float fac = BMO_slot_float_get(op->slots_in, "factor");
43  const int iterations = BMO_slot_int_get(op->slots_in, "iterations");
44  const int faces_num = BMO_slot_buffer_count(op->slots_in, "faces");
45 
46  const float eps = 0.00001f;
47  const float eps_sq = square_f(eps);
48 
49  BMOIter oiter;
50  BMFace *f;
51  BLI_mempool *vert_accum_pool;
52  GHash *vaccum_map;
53  float(*faces_center)[3];
54  int i, iter_step, shared_vert_num;
55 
56  faces_center = MEM_mallocN(sizeof(*faces_center) * faces_num, __func__);
57 
58  shared_vert_num = 0;
59  BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
60  BMLoop *l_iter, *l_first;
61 
62  if (f->len == 3) {
63  continue;
64  }
65 
66  BM_face_calc_center_median_weighted(f, faces_center[i]);
67 
68  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
69  do {
70  if (!BMO_vert_flag_test(bm, l_iter->v, ELE_VERT_ADJUST)) {
72  shared_vert_num += 1;
73  }
74  } while ((l_iter = l_iter->next) != l_first);
75 
77  }
78 
79  vert_accum_pool = BLI_mempool_create(sizeof(struct VertAccum), 0, 512, BLI_MEMPOOL_NOP);
80  vaccum_map = BLI_ghash_ptr_new_ex(__func__, shared_vert_num);
81 
82  for (iter_step = 0; iter_step < iterations; iter_step++) {
83  GHashIterator gh_iter;
84  bool changed = false;
85 
86  BMO_ITER_INDEX (f, &oiter, op->slots_in, "faces", BM_FACE, i) {
87  BMLoop *l_iter, *l_first;
88  float plane[4];
89 
91  continue;
92  }
94 
95  BLI_assert(f->len != 3);
96 
97  /* keep original face data (else we 'move' the face) */
98 #if 0
101 #endif
102 
103  plane_from_point_normal_v3(plane, faces_center[i], f->no);
104 
105  l_iter = l_first = BM_FACE_FIRST_LOOP(f);
106  do {
107  struct VertAccum *va;
108  void **va_p;
109  float co[3];
110 
111  if (!BLI_ghash_ensure_p(vaccum_map, l_iter->v, &va_p)) {
112  *va_p = BLI_mempool_calloc(vert_accum_pool);
113  }
114  va = *va_p;
115 
116  closest_to_plane_normalized_v3(co, plane, l_iter->v->co);
117  va->co_tot += 1;
118 
119  interp_v3_v3v3(va->co, va->co, co, 1.0f / (float)va->co_tot);
120  } while ((l_iter = l_iter->next) != l_first);
121  }
122 
123  GHASH_ITER (gh_iter, vaccum_map) {
124  BMVert *v = BLI_ghashIterator_getKey(&gh_iter);
125  struct VertAccum *va = BLI_ghashIterator_getValue(&gh_iter);
126  BMIter iter;
127 
128  if (len_squared_v3v3(v->co, va->co) > eps_sq) {
130  interp_v3_v3v3(v->co, v->co, va->co, fac);
131  changed = true;
132  }
133 
134  /* tag for re-calculation */
135  BM_ITER_ELEM (f, &iter, v, BM_FACES_OF_VERT) {
136  if (f->len != 3) {
138  }
139  }
140  }
141 
142  /* if nothing changed, break out early */
143  if (changed == false) {
144  break;
145  }
146 
147  BLI_ghash_clear(vaccum_map, NULL, NULL);
148  BLI_mempool_clear(vert_accum_pool);
149  }
150 
151  MEM_freeN(faces_center);
152  BLI_ghash_free(vaccum_map, NULL, NULL);
153  BLI_mempool_destroy(vert_accum_pool);
154 }
typedef float(TangentPoint)[2]
#define BLI_assert(a)
Definition: BLI_assert.h:58
BLI_INLINE void * BLI_ghashIterator_getKey(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:146
void BLI_ghash_clear(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:996
BLI_INLINE void * BLI_ghashIterator_getValue(GHashIterator *ghi) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.h:150
#define GHASH_ITER(gh_iter_, ghash_)
Definition: BLI_ghash.h:169
void BLI_ghash_free(GHash *gh, GHashKeyFreeFP keyfreefp, GHashValFreeFP valfreefp)
Definition: BLI_ghash.c:1008
GHash * BLI_ghash_ptr_new_ex(const char *info, const unsigned int nentries_reserve) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
bool BLI_ghash_ensure_p(GHash *gh, void *key, void ***r_val) ATTR_WARN_UNUSED_RESULT
Definition: BLI_ghash.c:851
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:243
void closest_to_plane_normalized_v3(float r_close[3], const float plane[4], const float pt[3])
Definition: math_geom.c:412
void interp_v3_v3v3(float r[3], const float a[3], const float b[3], const float t)
Definition: math_vector.c:49
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
void * BLI_mempool_calloc(BLI_mempool *pool) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT ATTR_NONNULL(1)
Definition: BLI_mempool.c:362
@ BLI_MEMPOOL_NOP
Definition: BLI_mempool.h:77
BLI_mempool * BLI_mempool_create(unsigned int esize, unsigned int totelem, unsigned int pchunk, unsigned int flag) ATTR_MALLOC ATTR_WARN_UNUSED_RESULT
Definition: BLI_mempool.c:268
void BLI_mempool_destroy(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:757
void BLI_mempool_clear(BLI_mempool *pool) ATTR_NONNULL(1)
Definition: BLI_mempool.c:749
Read Guarded memory(de)allocation.
@ BM_FACE
Definition: bmesh_class.h:386
#define BM_FACE_FIRST_LOOP(p)
Definition: bmesh_class.h:553
#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)
int BMO_slot_buffer_count(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_vert_flag_test(bm, e, oflag)
int BMO_slot_int_get(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:41
void *(* MEM_mallocN)(size_t len, const char *str)
Definition: mallocn.c:47
const btScalar eps
Definition: poly34.cpp:11
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 * next
Definition: bmesh_class.h:245
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]
float co[3]
Definition: bmesh_class.h:99
float co[3]