Blender  V2.93
mesh_fair.cc
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  * Mesh Fairing algorithm designed by Brett Fedack, used in the addon "Mesh Fairing":
17  * https://github.com/fedackb/mesh-fairing.
18  */
19 
24 #include "BLI_map.hh"
25 #include "BLI_math.h"
26 #include "BLI_vector.hh"
27 
28 #include "DNA_mesh_types.h"
29 #include "DNA_meshdata_types.h"
30 #include "DNA_object_types.h"
31 
32 #include "BKE_lib_id.h"
33 #include "BKE_lib_query.h"
34 #include "BKE_mesh.h"
35 #include "BKE_mesh_fair.h"
36 #include "BKE_mesh_mapping.h"
37 
38 #include "bmesh.h"
39 #include "bmesh_tools.h"
40 
41 #include "MEM_guardedalloc.h"
42 #include "eigen_capi.h"
43 
44 using blender::Map;
45 using blender::Vector;
46 using std::array;
47 
48 class VertexWeight {
49  public:
50  virtual float weight_at_index(const int index) = 0;
51  virtual ~VertexWeight() = default;
52 };
53 
54 class LoopWeight {
55  public:
56  virtual float weight_at_index(const int index) = 0;
57  virtual ~LoopWeight() = default;
58 };
59 
61  public:
62  /* Get coordinates of vertices which are adjacent to the loop with specified index. */
63  virtual void adjacents_coords_from_loop(const int loop,
64  float r_adj_next[3],
65  float r_adj_prev[3]) = 0;
66 
67  /* Get the other vertex index for a loop. */
68  virtual int other_vertex_index_from_loop(const int loop, const unsigned int v) = 0;
69 
71  {
72  return totvert_;
73  }
74 
76  {
77  return totvert_;
78  }
79 
81  {
82  return &vlmap_[v];
83  }
84 
85  float *vertex_deformation_co_get(const int v)
86  {
87  return co_[v];
88  }
89 
90  virtual ~FairingContext() = default;
91 
92  void fair_vertices(bool *affected,
93  const eMeshFairingDepth depth,
94  VertexWeight *vertex_weight,
95  LoopWeight *loop_weight)
96  {
97 
98  fair_vertices_ex(affected, (int)depth, vertex_weight, loop_weight);
99  }
100 
101  protected:
103 
104  int totvert_;
105  int totloop_;
106 
109 
110  private:
111  void fair_setup_fairing(const int v,
112  const int i,
113  LinearSolver *solver,
114  float multiplier,
115  const int depth,
116  Map<int, int> &vert_col_map,
117  VertexWeight *vertex_weight,
118  LoopWeight *loop_weight)
119  {
120  if (depth == 0) {
121  if (vert_col_map.contains(v)) {
122  const int j = vert_col_map.lookup(v);
123  EIG_linear_solver_matrix_add(solver, i, j, -multiplier);
124  return;
125  }
126  for (int j = 0; j < 3; j++) {
127  EIG_linear_solver_right_hand_side_add(solver, j, i, multiplier * co_[v][j]);
128  }
129  return;
130  }
131 
132  float w_ij_sum = 0;
133  const float w_i = vertex_weight->weight_at_index(v);
134  MeshElemMap *vlmap_elem = &vlmap_[v];
135  for (int l = 0; l < vlmap_elem->count; l++) {
136  const int l_index = vlmap_elem->indices[l];
137  const int other_vert = other_vertex_index_from_loop(l_index, v);
138  const float w_ij = loop_weight->weight_at_index(l_index);
139  w_ij_sum += w_ij;
140  fair_setup_fairing(other_vert,
141  i,
142  solver,
143  w_i * w_ij * multiplier,
144  depth - 1,
145  vert_col_map,
146  vertex_weight,
147  loop_weight);
148  }
149  fair_setup_fairing(v,
150  i,
151  solver,
152  -1 * w_i * w_ij_sum * multiplier,
153  depth - 1,
154  vert_col_map,
155  vertex_weight,
156  loop_weight);
157  }
158 
159  void fair_vertices_ex(const bool *affected,
160  const int order,
161  VertexWeight *vertex_weight,
162  LoopWeight *loop_weight)
163  {
164  Map<int, int> vert_col_map;
165  int num_affected_vertices = 0;
166  for (int i = 0; i < totvert_; i++) {
167  if (!affected[i]) {
168  continue;
169  }
170  vert_col_map.add(i, num_affected_vertices);
171  num_affected_vertices++;
172  }
173 
174  /* Early return, nothing to do. */
175  if (ELEM(num_affected_vertices, 0, totvert_)) {
176  return;
177  }
178 
179  /* Setup fairing matrices */
180  LinearSolver *solver = EIG_linear_solver_new(num_affected_vertices, num_affected_vertices, 3);
181  for (auto item : vert_col_map.items()) {
182  const int v = item.key;
183  const int col = item.value;
184  fair_setup_fairing(v, col, solver, 1.0f, order, vert_col_map, vertex_weight, loop_weight);
185  }
186 
187  /* Solve linear system */
188  EIG_linear_solver_solve(solver);
189 
190  /* Copy the result back to the mesh */
191  for (auto item : vert_col_map.items()) {
192  const int v = item.key;
193  const int col = item.value;
194  for (int j = 0; j < 3; j++) {
195  co_[v][j] = EIG_linear_solver_variable_get(solver, j, col);
196  }
197  }
198 
199  /* Free solver data */
200  EIG_linear_solver_delete(solver);
201  }
202 };
203 
205  public:
206  MeshFairingContext(Mesh *mesh, MVert *deform_mverts)
207  {
208  totvert_ = mesh->totvert;
209  totloop_ = mesh->totloop;
210 
211  medge_ = mesh->medge;
212  mpoly_ = mesh->mpoly;
213  mloop_ = mesh->mloop;
215  &vlmap_mem_,
216  mesh->mpoly,
217  mesh->mloop,
218  mesh->totvert,
219  mesh->totpoly,
220  mesh->totloop);
221 
222  /* Deformation coords. */
224  if (deform_mverts) {
225  for (int i = 0; i < mesh->totvert; i++) {
226  co_[i] = deform_mverts[i].co;
227  }
228  }
229  else {
230  for (int i = 0; i < mesh->totvert; i++) {
231  co_[i] = mesh->mvert[i].co;
232  }
233  }
234 
236  for (int i = 0; i < mesh->totpoly; i++) {
237  for (int l = 0; l < mesh->mpoly[i].totloop; l++) {
239  }
240  }
241  }
242 
244  {
247  }
248 
249  void adjacents_coords_from_loop(const int loop,
250  float r_adj_next[3],
251  float r_adj_prev[3]) override
252  {
253  const int vert = mloop_[loop].v;
254  const MPoly *p = &mpoly_[loop_to_poly_map_[loop]];
255  const int corner = poly_find_loop_from_vert(p, &mloop_[p->loopstart], vert);
256  copy_v3_v3(r_adj_next, co_[ME_POLY_LOOP_NEXT(mloop_, p, corner)->v]);
257  copy_v3_v3(r_adj_prev, co_[ME_POLY_LOOP_PREV(mloop_, p, corner)->v]);
258  }
259 
260  int other_vertex_index_from_loop(const int loop, const unsigned int v) override
261  {
262  MEdge *e = &medge_[mloop_[loop].e];
263  if (e->v1 == v) {
264  return e->v2;
265  }
266  return e->v1;
267  }
268 
269  protected:
275 };
276 
278  public:
280  {
281  this->bm = bm;
282  totvert_ = bm->totvert;
283  totloop_ = bm->totloop;
284 
287 
288  /* Deformation coords. */
289  co_.reserve(bm->totvert);
290  for (int i = 0; i < bm->totvert; i++) {
291  BMVert *v = BM_vert_at_index(bm, i);
292  co_[i] = v->co;
293  }
294 
296  vlmap_ = (MeshElemMap *)MEM_calloc_arrayN(sizeof(MeshElemMap), bm->totvert, "bmesh loop map");
297  vlmap_mem_ = (int *)MEM_malloc_arrayN(sizeof(int), bm->totloop, "bmesh loop map mempool");
298 
299  BMVert *v;
300  BMLoop *l;
301  BMIter iter;
302  BMIter loop_iter;
303  int index_iter = 0;
304 
305  /* This initializes both the bmloop and the vlmap for bmesh in a single loop. */
306  BM_ITER_MESH (v, &iter, bm, BM_VERTS_OF_MESH) {
307  int loop_count = 0;
308  const int vert_index = BM_elem_index_get(v);
309  vlmap_[vert_index].indices = &vlmap_mem_[index_iter];
310  BM_ITER_ELEM (l, &loop_iter, v, BM_LOOPS_OF_VERT) {
311  const int loop_index = BM_elem_index_get(l);
312  bmloop_[loop_index] = l;
313  vlmap_mem_[index_iter] = loop_index;
314  index_iter++;
315  loop_count++;
316  }
317  vlmap_[vert_index].count = loop_count;
318  }
319  }
320 
322  {
325  }
326 
327  void adjacents_coords_from_loop(const int loop,
328  float r_adj_next[3],
329  float r_adj_prev[3]) override
330  {
331  copy_v3_v3(r_adj_next, bmloop_[loop]->next->v->co);
332  copy_v3_v3(r_adj_prev, bmloop_[loop]->prev->v->co);
333  }
334 
335  int other_vertex_index_from_loop(const int loop, const unsigned int v) override
336  {
337  BMLoop *l = bmloop_[loop];
338  BMVert *bmvert = BM_vert_at_index(bm, v);
339  BMVert *bm_other_vert = BM_edge_other_vert(l->e, bmvert);
340  return BM_elem_index_get(bm_other_vert);
341  }
342 
343  protected:
346 };
347 
349  public:
351  {
352  const int totvert = fairing_context->vertex_count_get();
353  vertex_weights_.reserve(totvert);
354  for (int i = 0; i < totvert; i++) {
355  const int tot_loop = fairing_context->vertex_loop_map_get(i)->count;
356  if (tot_loop != 0) {
357  vertex_weights_[i] = 1.0f / tot_loop;
358  }
359  else {
360  vertex_weights_[i] = FLT_MAX;
361  }
362  }
363  }
364 
365  float weight_at_index(const int index) override
366  {
367  return vertex_weights_[index];
368  }
369 
370  private:
371  Vector<float> vertex_weights_;
372 };
373 
375 
376  public:
378  {
379 
380  const int totvert = fairing_context->vertex_count_get();
381  vertex_weights_.reserve(totvert);
382  for (int i = 0; i < totvert; i++) {
383 
384  float area = 0.0f;
385  float a[3];
386  copy_v3_v3(a, fairing_context->vertex_deformation_co_get(i));
387  const float acute_threshold = M_PI_2;
388 
389  MeshElemMap *vlmap_elem = fairing_context->vertex_loop_map_get(i);
390  for (int l = 0; l < vlmap_elem->count; l++) {
391  const int l_index = vlmap_elem->indices[l];
392 
393  float b[3], c[3], d[3];
394  fairing_context->adjacents_coords_from_loop(l_index, b, c);
395 
396  if (angle_v3v3v3(c, fairing_context->vertex_deformation_co_get(i), b) < acute_threshold) {
397  calc_circumcenter(d, a, b, c);
398  }
399  else {
400  add_v3_v3v3(d, b, c);
401  mul_v3_fl(d, 0.5f);
402  }
403 
404  float t[3];
405  add_v3_v3v3(t, a, b);
406  mul_v3_fl(t, 0.5f);
407  area += area_tri_v3(a, t, d);
408 
409  add_v3_v3v3(t, a, c);
410  mul_v3_fl(t, 0.5f);
411  area += area_tri_v3(a, d, t);
412  }
413 
414  vertex_weights_[i] = area != 0.0f ? 1.0f / area : 1e12;
415  }
416  }
417 
418  float weight_at_index(const int index) override
419  {
420  return vertex_weights_[index];
421  }
422 
423  private:
424  Vector<float> vertex_weights_;
425 
426  void calc_circumcenter(float r[3], const float a[3], const float b[3], const float c[3])
427  {
428  float ab[3];
429  sub_v3_v3v3(ab, b, a);
430 
431  float ac[3];
432  sub_v3_v3v3(ac, c, a);
433 
434  float ab_cross_ac[3];
435  cross_v3_v3v3(ab_cross_ac, ab, ac);
436 
437  if (len_squared_v3(ab_cross_ac) > 0.0f) {
438  float d[3];
439  cross_v3_v3v3(d, ab_cross_ac, ab);
440  mul_v3_fl(d, len_squared_v3(ac));
441 
442  float t[3];
443  cross_v3_v3v3(t, ac, ab_cross_ac);
444  mul_v3_fl(t, len_squared_v3(ab));
445 
446  add_v3_v3(d, t);
447 
448  mul_v3_fl(d, 1.0f / (2.0f * len_squared_v3(ab_cross_ac)));
449 
450  add_v3_v3v3(r, a, d);
451  return;
452  }
453  copy_v3_v3(r, a);
454  }
455 };
456 
458  public:
459  float weight_at_index(const int UNUSED(index)) override
460  {
461  return 1.0f;
462  }
463 };
464 
465 static void prefair_and_fair_vertices(FairingContext *fairing_context,
466  bool *affected_vertices,
467  const eMeshFairingDepth depth)
468 {
469  /* Prefair. */
470  UniformVertexWeight *uniform_vertex_weights = new UniformVertexWeight(fairing_context);
471  UniformLoopWeight *uniform_loop_weights = new UniformLoopWeight();
472  fairing_context->fair_vertices(
473  affected_vertices, depth, uniform_vertex_weights, uniform_loop_weights);
474  delete uniform_vertex_weights;
475 
476  /* Fair. */
477  VoronoiVertexWeight *voronoi_vertex_weights = new VoronoiVertexWeight(fairing_context);
478  /* TODO: Implement cotangent loop weights. */
479  fairing_context->fair_vertices(
480  affected_vertices, depth, voronoi_vertex_weights, uniform_loop_weights);
481 
482  delete uniform_loop_weights;
483  delete voronoi_vertex_weights;
484 }
485 
487  struct MVert *deform_mverts,
488  bool *affect_vertices,
489  const eMeshFairingDepth depth)
490 {
491  MeshFairingContext *fairing_context = new MeshFairingContext(mesh, deform_mverts);
492  prefair_and_fair_vertices(fairing_context, affect_vertices, depth);
493  delete fairing_context;
494 }
495 
497  bool *affect_vertices,
498  const eMeshFairingDepth depth)
499 {
500  BMeshFairingContext *fairing_context = new BMeshFairingContext(bm);
501  prefair_and_fair_vertices(fairing_context, affect_vertices, depth);
502  delete fairing_context;
503 }
int poly_find_loop_from_vert(const struct MPoly *poly, const struct MLoop *loopstart, uint vert)
eMeshFairingDepth
Definition: BKE_mesh_fair.h:36
void BKE_mesh_vert_loop_map_create(MeshElemMap **r_map, int **r_mem, const struct MPoly *mpoly, const struct MLoop *mloop, int totvert, int totpoly, int totloop)
#define M_PI_2
Definition: BLI_math_base.h:41
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:116
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE void add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
float angle_v3v3v3(const float a[3], const float b[3], const float c[3]) ATTR_WARN_UNUSED_RESULT
Definition: math_vector.c:417
MINLINE void add_v3_v3(float r[3], const float a[3])
#define UNUSED(x)
#define ELEM(...)
#define ME_POLY_LOOP_PREV(mloop, mp, i)
#define ME_POLY_LOOP_NEXT(mloop, mp, i)
Object is a sort of wrapper for general info.
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble GLdouble r _GL_VOID_RET _GL_VOID GLfloat GLfloat r _GL_VOID_RET _GL_VOID GLint GLint r _GL_VOID_RET _GL_VOID GLshort GLshort r _GL_VOID_RET _GL_VOID GLdouble GLdouble r
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint GLdouble GLdouble GLint GLint const GLdouble *points _GL_VOID_RET _GL_VOID GLdouble GLdouble u2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLdouble GLdouble v2 _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLdouble GLdouble nz _GL_VOID_RET _GL_VOID GLfloat GLfloat nz _GL_VOID_RET _GL_VOID GLint GLint nz _GL_VOID_RET _GL_VOID GLshort GLshort nz _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const GLfloat *values _GL_VOID_RET _GL_VOID GLsizei const GLushort *values _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID const GLuint const GLclampf *priorities _GL_VOID_RET _GL_VOID GLdouble y _GL_VOID_RET _GL_VOID GLfloat y _GL_VOID_RET _GL_VOID GLint y _GL_VOID_RET _GL_VOID GLshort y _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLfloat GLfloat z _GL_VOID_RET _GL_VOID GLint GLint z _GL_VOID_RET _GL_VOID GLshort GLshort z _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble w _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat w _GL_VOID_RET _GL_VOID GLint GLint GLint w _GL_VOID_RET _GL_VOID GLshort GLshort GLshort w _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble y2 _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat y2 _GL_VOID_RET _GL_VOID GLint GLint GLint y2 _GL_VOID_RET _GL_VOID GLshort GLshort GLshort y2 _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLdouble GLdouble z _GL_VOID_RET _GL_VOID GLuint *buffer _GL_VOID_RET _GL_VOID GLdouble t _GL_VOID_RET _GL_VOID GLfloat t _GL_VOID_RET _GL_VOID GLint t _GL_VOID_RET _GL_VOID GLshort t _GL_VOID_RET _GL_VOID GLdouble t
_GL_VOID GLfloat value _GL_VOID_RET _GL_VOID const GLuint GLboolean *residences _GL_BOOL_RET _GL_VOID GLsizei GLfloat GLfloat GLfloat GLfloat const GLubyte *bitmap _GL_VOID_RET _GL_VOID GLenum const void *lists _GL_VOID_RET _GL_VOID const GLdouble *equation _GL_VOID_RET _GL_VOID GLdouble GLdouble blue _GL_VOID_RET _GL_VOID GLfloat GLfloat blue _GL_VOID_RET _GL_VOID GLint GLint blue _GL_VOID_RET _GL_VOID GLshort GLshort blue _GL_VOID_RET _GL_VOID GLubyte GLubyte blue _GL_VOID_RET _GL_VOID GLuint GLuint blue _GL_VOID_RET _GL_VOID GLushort GLushort blue _GL_VOID_RET _GL_VOID GLbyte GLbyte GLbyte alpha _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble alpha _GL_VOID_RET _GL_VOID GLfloat GLfloat GLfloat alpha _GL_VOID_RET _GL_VOID GLint GLint GLint alpha _GL_VOID_RET _GL_VOID GLshort GLshort GLshort alpha _GL_VOID_RET _GL_VOID GLubyte GLubyte GLubyte alpha _GL_VOID_RET _GL_VOID GLuint GLuint GLuint alpha _GL_VOID_RET _GL_VOID GLushort GLushort GLushort alpha _GL_VOID_RET _GL_VOID GLenum mode _GL_VOID_RET _GL_VOID GLint GLsizei GLsizei GLenum type _GL_VOID_RET _GL_VOID GLsizei GLenum GLenum const void *pixels _GL_VOID_RET _GL_VOID const void *pointer _GL_VOID_RET _GL_VOID GLdouble v _GL_VOID_RET _GL_VOID GLfloat v _GL_VOID_RET _GL_VOID GLint GLint i2 _GL_VOID_RET _GL_VOID GLint j _GL_VOID_RET _GL_VOID GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLdouble GLdouble GLdouble GLdouble GLdouble zFar _GL_VOID_RET _GL_UINT GLdouble *equation _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLenum GLfloat *v _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLfloat *values _GL_VOID_RET _GL_VOID GLushort *values _GL_VOID_RET _GL_VOID GLenum GLfloat *params _GL_VOID_RET _GL_VOID GLenum GLdouble *params _GL_VOID_RET _GL_VOID GLenum GLint *params _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_VOID GLsizei const void *pointer _GL_VOID_RET _GL_BOOL GLfloat param _GL_VOID_RET _GL_VOID GLint param _GL_VOID_RET _GL_VOID GLenum GLfloat param _GL_VOID_RET _GL_VOID GLenum GLint param _GL_VOID_RET _GL_VOID GLushort pattern _GL_VOID_RET _GL_VOID GLdouble GLdouble GLint GLint order
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
@ BM_LOOP
Definition: bmesh_class.h:385
@ BM_VERT
Definition: bmesh_class.h:383
#define BM_elem_index_get(ele)
Definition: bmesh_inline.h:124
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
@ BM_VERTS_OF_MESH
@ BM_LOOPS_OF_VERT
ATTR_WARN_UNUSED_RESULT BMesh * bm
void BM_mesh_elem_table_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2276
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
Definition: bmesh_mesh.c:2152
BLI_INLINE BMVert * BM_vert_at_index(BMesh *bm, const int index)
Definition: bmesh_mesh.h:98
BLI_INLINE BMVert * BM_edge_other_vert(BMEdge *e, const BMVert *v) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMLoop * l
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
int other_vertex_index_from_loop(const int loop, const unsigned int v) override
Definition: mesh_fair.cc:335
~BMeshFairingContext() override
Definition: mesh_fair.cc:321
BMeshFairingContext(BMesh *bm)
Definition: mesh_fair.cc:279
void adjacents_coords_from_loop(const int loop, float r_adj_next[3], float r_adj_prev[3]) override
Definition: mesh_fair.cc:327
Vector< BMLoop * > bmloop_
Definition: mesh_fair.cc:345
int loop_count_get()
Definition: mesh_fair.cc:75
int vertex_count_get()
Definition: mesh_fair.cc:70
Vector< float * > co_
Definition: mesh_fair.cc:102
virtual ~FairingContext()=default
virtual int other_vertex_index_from_loop(const int loop, const unsigned int v)=0
int * vlmap_mem_
Definition: mesh_fair.cc:108
MeshElemMap * vertex_loop_map_get(const int v)
Definition: mesh_fair.cc:80
virtual void adjacents_coords_from_loop(const int loop, float r_adj_next[3], float r_adj_prev[3])=0
MeshElemMap * vlmap_
Definition: mesh_fair.cc:107
float * vertex_deformation_co_get(const int v)
Definition: mesh_fair.cc:85
void fair_vertices(bool *affected, const eMeshFairingDepth depth, VertexWeight *vertex_weight, LoopWeight *loop_weight)
Definition: mesh_fair.cc:92
virtual float weight_at_index(const int index)=0
virtual ~LoopWeight()=default
void adjacents_coords_from_loop(const int loop, float r_adj_next[3], float r_adj_prev[3]) override
Definition: mesh_fair.cc:249
MeshFairingContext(Mesh *mesh, MVert *deform_mverts)
Definition: mesh_fair.cc:206
int other_vertex_index_from_loop(const int loop, const unsigned int v) override
Definition: mesh_fair.cc:260
Vector< int > loop_to_poly_map_
Definition: mesh_fair.cc:274
~MeshFairingContext() override
Definition: mesh_fair.cc:243
float weight_at_index(const int UNUSED(index)) override
Definition: mesh_fair.cc:459
float weight_at_index(const int index) override
Definition: mesh_fair.cc:365
UniformVertexWeight(FairingContext *fairing_context)
Definition: mesh_fair.cc:350
virtual float weight_at_index(const int index)=0
virtual ~VertexWeight()=default
VoronoiVertexWeight(FairingContext *fairing_context)
Definition: mesh_fair.cc:377
float weight_at_index(const int index) override
Definition: mesh_fair.cc:418
bool add(const Key &key, const Value &value)
Definition: BLI_map.hh:264
const Value & lookup(const Key &key) const
Definition: BLI_map.hh:499
ItemIterator items() const
Definition: BLI_map.hh:825
bool contains(const Key &key) const
Definition: BLI_map.hh:322
void reserve(const int64_t min_capacity)
Definition: BLI_vector.hh:355
uint col
LinearSolver * EIG_linear_solver_new(int num_rows, int num_columns, int num_rhs)
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
void EIG_linear_solver_delete(LinearSolver *solver)
double EIG_linear_solver_variable_get(LinearSolver *solver, int rhs, int index)
void EIG_linear_solver_matrix_add(LinearSolver *solver, int row, int col, double value)
bool EIG_linear_solver_solve(LinearSolver *solver)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:48
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:46
static ulong * next
void BKE_mesh_prefair_and_fair_vertices(struct Mesh *mesh, struct MVert *deform_mverts, bool *affect_vertices, const eMeshFairingDepth depth)
Definition: mesh_fair.cc:486
static void prefair_and_fair_vertices(FairingContext *fairing_context, bool *affected_vertices, const eMeshFairingDepth depth)
Definition: mesh_fair.cc:465
void BKE_bmesh_prefair_and_fair_vertices(struct BMesh *bm, bool *affect_vertices, const eMeshFairingDepth depth)
Definition: mesh_fair.cc:496
static unsigned c
Definition: RandGen.cpp:97
static unsigned a[3]
Definition: RandGen.cpp:92
static void area(int d1, int d2, int e1, int e2, float weights[2])
struct BMEdge * e
Definition: bmesh_class.h:176
float co[3]
Definition: bmesh_class.h:99
int totvert
Definition: bmesh_class.h:297
int totloop
Definition: bmesh_class.h:297
unsigned int e
unsigned int v
float co[3]
struct MEdge * medge
struct MVert * mvert
int totvert
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly