Blender  V3.3
MOD_laplaciansmooth.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-or-later
2  * Copyright 2005 Blender Foundation. All rights reserved. */
3 
8 #include "BLI_utildefines.h"
9 
10 #include "BLI_math.h"
11 
12 #include "BLT_translation.h"
13 
14 #include "DNA_defaults.h"
15 #include "DNA_mesh_types.h"
16 #include "DNA_meshdata_types.h"
17 #include "DNA_object_types.h"
18 #include "DNA_screen_types.h"
19 
20 #include "MEM_guardedalloc.h"
21 
22 #include "BKE_context.h"
23 #include "BKE_deform.h"
24 #include "BKE_editmesh.h"
25 #include "BKE_lib_id.h"
26 #include "BKE_mesh.h"
27 #include "BKE_mesh_wrapper.h"
28 #include "BKE_modifier.h"
29 #include "BKE_screen.h"
30 
31 #include "UI_interface.h"
32 #include "UI_resources.h"
33 
34 #include "RNA_access.h"
35 #include "RNA_prototypes.h"
36 
37 #include "MOD_ui_common.h"
38 #include "MOD_util.h"
39 
40 #include "eigen_capi.h"
41 
42 struct BLaplacianSystem {
43  float *eweights; /* Length weights per Edge */
44  float (*fweights)[3]; /* Cotangent weights per face */
45  float *ring_areas; /* Total area per ring. */
46  float *vlengths; /* Total sum of lengths(edges) per vertex. */
47  float *vweights; /* Total sum of weights per vertex. */
48  int edges_num; /* Number of edges. */
49  int loops_num; /* Number of edges. */
50  int polys_num; /* Number of faces. */
51  int verts_num; /* Number of verts. */
52  short *ne_fa_num; /* Number of neighbors faces around vertex. */
53  short *ne_ed_num; /* Number of neighbors Edges around vertex. */
54  bool *zerola; /* Is zero area or length. */
55 
56  /* Pointers to data. */
58  const MPoly *mpoly;
59  const MLoop *mloop;
60  const MEdge *medges;
62 
63  /* Data. */
64  float min_area;
65  float vert_centroid[3];
66 };
67 typedef struct BLaplacianSystem LaplacianSystem;
68 
69 static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks);
70 static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams);
71 static float compute_volume(const float center[3],
72  float (*vertexCos)[3],
73  const MPoly *mpoly,
74  int polys_num,
75  const MLoop *mloop);
76 static LaplacianSystem *init_laplacian_system(int a_numEdges,
77  int a_numPolys,
78  int a_numLoops,
79  int a_numVerts);
81 static void fill_laplacian_matrix(LaplacianSystem *sys);
82 static void init_data(ModifierData *md);
83 static void init_laplacian_matrix(LaplacianSystem *sys);
84 static void memset_laplacian_system(LaplacianSystem *sys, int val);
85 static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag);
86 static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border);
87 
89 {
90  MEM_SAFE_FREE(sys->eweights);
91  MEM_SAFE_FREE(sys->fweights);
92  MEM_SAFE_FREE(sys->ne_ed_num);
93  MEM_SAFE_FREE(sys->ne_fa_num);
94  MEM_SAFE_FREE(sys->ring_areas);
95  MEM_SAFE_FREE(sys->vlengths);
96  MEM_SAFE_FREE(sys->vweights);
97  MEM_SAFE_FREE(sys->zerola);
98 
99  if (sys->context) {
101  }
102  sys->vertexCos = NULL;
103  sys->mpoly = NULL;
104  sys->mloop = NULL;
105  sys->medges = NULL;
106  MEM_freeN(sys);
107 }
108 
109 static void memset_laplacian_system(LaplacianSystem *sys, int val)
110 {
111  memset(sys->eweights, val, sizeof(float) * sys->edges_num);
112  memset(sys->fweights, val, sizeof(float[3]) * sys->loops_num);
113  memset(sys->ne_ed_num, val, sizeof(short) * sys->verts_num);
114  memset(sys->ne_fa_num, val, sizeof(short) * sys->verts_num);
115  memset(sys->ring_areas, val, sizeof(float) * sys->verts_num);
116  memset(sys->vlengths, val, sizeof(float) * sys->verts_num);
117  memset(sys->vweights, val, sizeof(float) * sys->verts_num);
118  memset(sys->zerola, val, sizeof(bool) * sys->verts_num);
119 }
120 
121 static LaplacianSystem *init_laplacian_system(int a_numEdges,
122  int a_numPolys,
123  int a_numLoops,
124  int a_numVerts)
125 {
126  LaplacianSystem *sys;
127  sys = MEM_callocN(sizeof(LaplacianSystem), "ModLaplSmoothSystem");
128  sys->edges_num = a_numEdges;
129  sys->polys_num = a_numPolys;
130  sys->loops_num = a_numLoops;
131  sys->verts_num = a_numVerts;
132 
133  sys->eweights = MEM_calloc_arrayN(sys->edges_num, sizeof(float), __func__);
134  sys->fweights = MEM_calloc_arrayN(sys->loops_num, sizeof(float[3]), __func__);
135  sys->ne_ed_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__);
136  sys->ne_fa_num = MEM_calloc_arrayN(sys->verts_num, sizeof(short), __func__);
137  sys->ring_areas = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
138  sys->vlengths = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
139  sys->vweights = MEM_calloc_arrayN(sys->verts_num, sizeof(float), __func__);
140  sys->zerola = MEM_calloc_arrayN(sys->verts_num, sizeof(bool), __func__);
141 
142  return sys;
143 }
144 
145 static float compute_volume(const float center[3],
146  float (*vertexCos)[3],
147  const MPoly *mpoly,
148  int polys_num,
149  const MLoop *mloop)
150 {
151  int i;
152  float vol = 0.0f;
153 
154  for (i = 0; i < polys_num; i++) {
155  const MPoly *mp = &mpoly[i];
156  const MLoop *l_first = &mloop[mp->loopstart];
157  const MLoop *l_prev = l_first + 1;
158  const MLoop *l_curr = l_first + 2;
159  const MLoop *l_term = l_first + mp->totloop;
160 
161  for (; l_curr != l_term; l_prev = l_curr, l_curr++) {
163  center, vertexCos[l_first->v], vertexCos[l_prev->v], vertexCos[l_curr->v]);
164  }
165  }
166 
167  return fabsf(vol);
168 }
169 
170 static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag)
171 {
172  float beta;
173  int i;
174 
175  if (vend != 0.0f) {
176  beta = pow(vini / vend, 1.0f / 3.0f);
177  for (i = 0; i < sys->verts_num; i++) {
178  if (flag & MOD_LAPLACIANSMOOTH_X) {
179  sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) * beta +
180  sys->vert_centroid[0];
181  }
182  if (flag & MOD_LAPLACIANSMOOTH_Y) {
183  sys->vertexCos[i][1] = (sys->vertexCos[i][1] - sys->vert_centroid[1]) * beta +
184  sys->vert_centroid[1];
185  }
186  if (flag & MOD_LAPLACIANSMOOTH_Z) {
187  sys->vertexCos[i][2] = (sys->vertexCos[i][2] - sys->vert_centroid[2]) * beta +
188  sys->vert_centroid[2];
189  }
190  }
191  }
192 }
193 
195 {
196  float *v1, *v2;
197  float w1, w2, w3;
198  float areaf;
199  int i;
200  uint idv1, idv2;
201 
202  for (i = 0; i < sys->edges_num; i++) {
203  idv1 = sys->medges[i].v1;
204  idv2 = sys->medges[i].v2;
205 
206  v1 = sys->vertexCos[idv1];
207  v2 = sys->vertexCos[idv2];
208 
209  sys->ne_ed_num[idv1] = sys->ne_ed_num[idv1] + 1;
210  sys->ne_ed_num[idv2] = sys->ne_ed_num[idv2] + 1;
211  w1 = len_v3v3(v1, v2);
212  if (w1 < sys->min_area) {
213  sys->zerola[idv1] = true;
214  sys->zerola[idv2] = true;
215  }
216  else {
217  w1 = 1.0f / w1;
218  }
219 
220  sys->eweights[i] = w1;
221  }
222 
223  for (i = 0; i < sys->polys_num; i++) {
224  const MPoly *mp = &sys->mpoly[i];
225  const MLoop *l_next = &sys->mloop[mp->loopstart];
226  const MLoop *l_term = l_next + mp->totloop;
227  const MLoop *l_prev = l_term - 2;
228  const MLoop *l_curr = l_term - 1;
229 
230  for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
231  const float *v_prev = sys->vertexCos[l_prev->v];
232  const float *v_curr = sys->vertexCos[l_curr->v];
233  const float *v_next = sys->vertexCos[l_next->v];
234  const uint l_curr_index = l_curr - sys->mloop;
235 
236  sys->ne_fa_num[l_curr->v] += 1;
237 
238  areaf = area_tri_v3(v_prev, v_curr, v_next);
239 
240  if (areaf < sys->min_area) {
241  sys->zerola[l_curr->v] = true;
242  }
243 
244  sys->ring_areas[l_prev->v] += areaf;
245  sys->ring_areas[l_curr->v] += areaf;
246  sys->ring_areas[l_next->v] += areaf;
247 
248  w1 = cotangent_tri_weight_v3(v_curr, v_next, v_prev) / 2.0f;
249  w2 = cotangent_tri_weight_v3(v_next, v_prev, v_curr) / 2.0f;
250  w3 = cotangent_tri_weight_v3(v_prev, v_curr, v_next) / 2.0f;
251 
252  sys->fweights[l_curr_index][0] += w1;
253  sys->fweights[l_curr_index][1] += w2;
254  sys->fweights[l_curr_index][2] += w3;
255 
256  sys->vweights[l_curr->v] += w2 + w3;
257  sys->vweights[l_next->v] += w1 + w3;
258  sys->vweights[l_prev->v] += w1 + w2;
259  }
260  }
261  for (i = 0; i < sys->edges_num; i++) {
262  idv1 = sys->medges[i].v1;
263  idv2 = sys->medges[i].v2;
264  /* if is boundary, apply scale-dependent umbrella operator only with neighbors in boundary */
265  if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] &&
266  sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2]) {
267  sys->vlengths[idv1] += sys->eweights[i];
268  sys->vlengths[idv2] += sys->eweights[i];
269  }
270  }
271 }
272 
274 {
275  int i;
276  uint idv1, idv2;
277 
278  for (i = 0; i < sys->polys_num; i++) {
279  const MPoly *mp = &sys->mpoly[i];
280  const MLoop *l_next = &sys->mloop[mp->loopstart];
281  const MLoop *l_term = l_next + mp->totloop;
282  const MLoop *l_prev = l_term - 2;
283  const MLoop *l_curr = l_term - 1;
284 
285  for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
286  const uint l_curr_index = l_curr - sys->mloop;
287 
288  /* Is ring if number of faces == number of edges around vertex. */
289  if (sys->ne_ed_num[l_curr->v] == sys->ne_fa_num[l_curr->v] &&
290  sys->zerola[l_curr->v] == false) {
292  l_curr->v,
293  l_next->v,
294  sys->fweights[l_curr_index][2] * sys->vweights[l_curr->v]);
296  l_curr->v,
297  l_prev->v,
298  sys->fweights[l_curr_index][1] * sys->vweights[l_curr->v]);
299  }
300  if (sys->ne_ed_num[l_next->v] == sys->ne_fa_num[l_next->v] &&
301  sys->zerola[l_next->v] == false) {
303  l_next->v,
304  l_curr->v,
305  sys->fweights[l_curr_index][2] * sys->vweights[l_next->v]);
307  l_next->v,
308  l_prev->v,
309  sys->fweights[l_curr_index][0] * sys->vweights[l_next->v]);
310  }
311  if (sys->ne_ed_num[l_prev->v] == sys->ne_fa_num[l_prev->v] &&
312  sys->zerola[l_prev->v] == false) {
314  l_prev->v,
315  l_curr->v,
316  sys->fweights[l_curr_index][1] * sys->vweights[l_prev->v]);
318  l_prev->v,
319  l_next->v,
320  sys->fweights[l_curr_index][0] * sys->vweights[l_prev->v]);
321  }
322  }
323  }
324 
325  for (i = 0; i < sys->edges_num; i++) {
326  idv1 = sys->medges[i].v1;
327  idv2 = sys->medges[i].v2;
328  /* Is boundary */
329  if (sys->ne_ed_num[idv1] != sys->ne_fa_num[idv1] &&
330  sys->ne_ed_num[idv2] != sys->ne_fa_num[idv2] && sys->zerola[idv1] == false &&
331  sys->zerola[idv2] == false) {
333  sys->context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]);
335  sys->context, idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]);
336  }
337  }
338 }
339 
340 static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
341 {
342  int i;
343  float lam;
344  float vini = 0.0f, vend = 0.0f;
345 
347  vini = compute_volume(
348  sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
349  }
350  for (i = 0; i < sys->verts_num; i++) {
351  if (sys->zerola[i] == false) {
352  lam = sys->ne_ed_num[i] == sys->ne_fa_num[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) :
353  (lambda_border >= 0.0f ? 1.0f : -1.0f);
354  if (flag & MOD_LAPLACIANSMOOTH_X) {
355  sys->vertexCos[i][0] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 0, i) -
356  sys->vertexCos[i][0]);
357  }
358  if (flag & MOD_LAPLACIANSMOOTH_Y) {
359  sys->vertexCos[i][1] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 1, i) -
360  sys->vertexCos[i][1]);
361  }
362  if (flag & MOD_LAPLACIANSMOOTH_Z) {
363  sys->vertexCos[i][2] += lam * ((float)EIG_linear_solver_variable_get(sys->context, 2, i) -
364  sys->vertexCos[i][2]);
365  }
366  }
367  }
369  vend = compute_volume(
370  sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->polys_num, sys->mloop);
371  volume_preservation(sys, vini, vend, flag);
372  }
373 }
374 
376  LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float (*vertexCos)[3], int verts_num)
377 {
378  LaplacianSystem *sys;
379  MDeformVert *dvert = NULL;
380  MDeformVert *dv = NULL;
381  float w, wpaint;
382  int i, iter;
383  int defgrp_index;
384  const bool invert_vgroup = (smd->flag & MOD_LAPLACIANSMOOTH_INVERT_VGROUP) != 0;
385 
387  if (!sys) {
388  return;
389  }
390 
391  sys->mpoly = mesh->mpoly;
392  sys->mloop = mesh->mloop;
393  sys->medges = mesh->medge;
394  sys->vertexCos = vertexCos;
395  sys->min_area = 0.00001f;
396  MOD_get_vgroup(ob, mesh, smd->defgrp_name, &dvert, &defgrp_index);
397 
398  sys->vert_centroid[0] = 0.0f;
399  sys->vert_centroid[1] = 0.0f;
400  sys->vert_centroid[2] = 0.0f;
401  memset_laplacian_system(sys, 0);
402 
404 
406 
407  for (iter = 0; iter < smd->repeat; iter++) {
408  for (i = 0; i < verts_num; i++) {
412  if (iter == 0) {
413  add_v3_v3(sys->vert_centroid, vertexCos[i]);
414  }
415  }
416  if (iter == 0 && verts_num > 0) {
417  mul_v3_fl(sys->vert_centroid, 1.0f / (float)verts_num);
418  }
419 
420  dv = dvert;
421  for (i = 0; i < verts_num; i++) {
425  if (iter == 0) {
426  if (dv) {
427  wpaint = invert_vgroup ? 1.0f - BKE_defvert_find_weight(dv, defgrp_index) :
428  BKE_defvert_find_weight(dv, defgrp_index);
429  dv++;
430  }
431  else {
432  wpaint = 1.0f;
433  }
434 
435  if (sys->zerola[i] == false) {
437  w = sys->vweights[i];
438  sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / w;
439  w = sys->vlengths[i];
440  sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
441  if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) {
442  EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f + fabsf(smd->lambda) * wpaint);
443  }
444  else {
446  sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
447  }
448  }
449  else {
450  w = sys->vweights[i] * sys->ring_areas[i];
451  sys->vweights[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda) * wpaint / (4.0f * w);
452  w = sys->vlengths[i];
453  sys->vlengths[i] = (w == 0.0f) ? 0.0f : -fabsf(smd->lambda_border) * wpaint * 2.0f / w;
454 
455  if (sys->ne_ed_num[i] == sys->ne_fa_num[i]) {
457  i,
458  i,
459  1.0f + fabsf(smd->lambda) * wpaint /
460  (4.0f * sys->ring_areas[i]));
461  }
462  else {
464  sys->context, i, i, 1.0f + fabsf(smd->lambda_border) * wpaint * 2.0f);
465  }
466  }
467  }
468  else {
469  EIG_linear_solver_matrix_add(sys->context, i, i, 1.0f);
470  }
471  }
472  }
473 
474  if (iter == 0) {
476  }
477 
478  if (EIG_linear_solver_solve(sys->context)) {
479  validate_solution(sys, smd->flag, smd->lambda, smd->lambda_border);
480  }
481  }
483  sys->context = NULL;
484 
486 }
487 
488 static void init_data(ModifierData *md)
489 {
491 
492  BLI_assert(MEMCMP_STRUCT_AFTER_IS_ZERO(smd, modifier));
493 
495 }
496 
497 static bool is_disabled(const struct Scene *UNUSED(scene),
498  ModifierData *md,
499  bool UNUSED(useRenderParams))
500 {
502  short flag;
503 
505 
506  /* disable if modifier is off for X, Y and Z or if factor is 0 */
507  if (flag == 0) {
508  return 1;
509  }
510 
511  return 0;
512 }
513 
515  ModifierData *md,
516  CustomData_MeshMasks *r_cddata_masks)
517 {
519 
520  /* ask for vertexgroups if we need them */
521  if (smd->defgrp_name[0] != '\0') {
522  r_cddata_masks->vmask |= CD_MASK_MDEFORMVERT;
523  }
524 }
525 
526 static void deformVerts(ModifierData *md,
527  const ModifierEvalContext *ctx,
528  Mesh *mesh,
529  float (*vertexCos)[3],
530  int verts_num)
531 {
532  Mesh *mesh_src;
533 
534  if (verts_num == 0) {
535  return;
536  }
537 
538  mesh_src = MOD_deform_mesh_eval_get(ctx->object, NULL, mesh, NULL, verts_num, false, false);
539 
541  (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
542 
543  if (!ELEM(mesh_src, NULL, mesh)) {
544  BKE_id_free(NULL, mesh_src);
545  }
546 }
547 
548 static void deformVertsEM(ModifierData *md,
549  const ModifierEvalContext *ctx,
550  struct BMEditMesh *editData,
551  Mesh *mesh,
552  float (*vertexCos)[3],
553  int verts_num)
554 {
555  Mesh *mesh_src;
556 
557  if (verts_num == 0) {
558  return;
559  }
560 
561  mesh_src = MOD_deform_mesh_eval_get(ctx->object, editData, mesh, NULL, verts_num, false, false);
562 
563  /* TODO(Campbell): use edit-mode data only (remove this line). */
564  if (mesh_src != NULL) {
566  }
567 
569  (LaplacianSmoothModifierData *)md, ctx->object, mesh_src, vertexCos, verts_num);
570 
571  if (!ELEM(mesh_src, NULL, mesh)) {
572  BKE_id_free(NULL, mesh_src);
573  }
574 }
575 
576 static void panel_draw(const bContext *UNUSED(C), Panel *panel)
577 {
578  uiLayout *row;
579  uiLayout *layout = panel->layout;
581 
582  PointerRNA ob_ptr;
584 
585  uiLayoutSetPropSep(layout, true);
586 
587  uiItemR(layout, ptr, "iterations", 0, NULL, ICON_NONE);
588 
589  row = uiLayoutRowWithHeading(layout, true, IFACE_("Axis"));
590  uiItemR(row, ptr, "use_x", toggles_flag, NULL, ICON_NONE);
591  uiItemR(row, ptr, "use_y", toggles_flag, NULL, ICON_NONE);
592  uiItemR(row, ptr, "use_z", toggles_flag, NULL, ICON_NONE);
593 
594  uiItemR(layout, ptr, "lambda_factor", 0, NULL, ICON_NONE);
595  uiItemR(layout, ptr, "lambda_border", 0, NULL, ICON_NONE);
596 
597  uiItemR(layout, ptr, "use_volume_preserve", 0, NULL, ICON_NONE);
598  uiItemR(layout, ptr, "use_normalized", 0, NULL, ICON_NONE);
599 
600  modifier_vgroup_ui(layout, ptr, &ob_ptr, "vertex_group", "invert_vertex_group", NULL);
601 
602  modifier_panel_end(layout, ptr);
603 }
604 
605 static void panelRegister(ARegionType *region_type)
606 {
608 }
609 
611  /* name */ N_("LaplacianSmooth"),
612  /* structName */ "LaplacianSmoothModifierData",
613  /* structSize */ sizeof(LaplacianSmoothModifierData),
614  /* srna */ &RNA_LaplacianSmoothModifier,
615  /* type */ eModifierTypeType_OnlyDeform,
617  /* icon */ ICON_MOD_SMOOTH,
618 
619  /* copyData */ BKE_modifier_copydata_generic,
620 
621  /* deformVerts */ deformVerts,
622  /* deformMatrices */ NULL,
623  /* deformVertsEM */ deformVertsEM,
624  /* deformMatricesEM */ NULL,
625  /* modifyMesh */ NULL,
626  /* modifyGeometrySet */ NULL,
627 
628  /* initData */ init_data,
629  /* requiredDataMask */ required_data_mask,
630  /* freeData */ NULL,
631  /* isDisabled */ is_disabled,
632  /* updateDepsgraph */ NULL,
633  /* dependsOnTime */ NULL,
634  /* dependsOnNormals */ NULL,
635  /* foreachIDLink */ NULL,
636  /* foreachTexLink */ NULL,
637  /* freeRuntimeData */ NULL,
638  /* panelRegister */ panelRegister,
639  /* blendWrite */ NULL,
640  /* blendRead */ NULL,
641 };
typedef float(TangentPoint)[2]
support for deformation groups and hooks.
float BKE_defvert_find_weight(const struct MDeformVert *dvert, int defgroup)
Definition: deform.c:704
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
Definition: mesh_wrapper.cc:94
@ eModifierTypeFlag_SupportsEditmode
Definition: BKE_modifier.h:69
@ eModifierTypeFlag_AcceptsMesh
Definition: BKE_modifier.h:66
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, int flag)
@ eModifierTypeType_OnlyDeform
Definition: BKE_modifier.h:44
#define BLI_assert(a)
Definition: BLI_assert.h:46
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:92
float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
Definition: math_geom.c:243
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
Definition: math_geom.c:190
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void mul_v3_fl(float r[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
unsigned int uint
Definition: BLI_sys_types.h:67
#define UNUSED(x)
#define ELEM(...)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define IFACE_(msgid)
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
Definition: DNA_defaults.h:29
@ MOD_LAPLACIANSMOOTH_X
@ MOD_LAPLACIANSMOOTH_Y
@ MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME
@ MOD_LAPLACIANSMOOTH_NORMALIZED
@ MOD_LAPLACIANSMOOTH_Z
@ MOD_LAPLACIANSMOOTH_INVERT_VGROUP
struct LaplacianSmoothModifierData LaplacianSmoothModifierData
@ eModifierType_LaplacianSmooth
Object is a sort of wrapper for general info.
NSNotificationCenter * center
_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 v1
Read Guarded memory(de)allocation.
#define MEM_SAFE_FREE(v)
static void init_data(ModifierData *md)
static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int verts_num)
static void laplaciansmoothModifier_do(LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float(*vertexCos)[3], int verts_num)
ModifierTypeInfo modifierType_LaplacianSmooth
static void init_laplacian_matrix(LaplacianSystem *sys)
static void delete_laplacian_system(LaplacianSystem *sys)
static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag)
static void memset_laplacian_system(LaplacianSystem *sys, int val)
static void required_data_mask(Object *ob, ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
static void panel_draw(const bContext *UNUSED(C), Panel *panel)
static void fill_laplacian_matrix(LaplacianSystem *sys)
static float compute_volume(const float center[3], float(*vertexCos)[3], const MPoly *mpoly, int polys_num, const MLoop *mloop)
static void panelRegister(ARegionType *region_type)
static LaplacianSystem * init_laplacian_system(int a_numEdges, int a_numPolys, int a_numLoops, int a_numVerts)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
Definition: MOD_ui_common.c:91
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
Mesh * MOD_deform_mesh_eval_get(Object *ob, struct BMEditMesh *em, Mesh *mesh, const float(*vertexCos)[3], const int verts_num, const bool use_normals, const bool use_orco)
Definition: MOD_util.c:167
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
Definition: MOD_util.c:235
#define C
Definition: RandGen.cpp:25
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
@ UI_ITEM_R_TOGGLE
@ UI_ITEM_R_FORCE_BLANK_DECORATE
void uiItemR(uiLayout *layout, struct PointerRNA *ptr, const char *propname, int flag, const char *name, int icon)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
Definition: btQuadWord.h:119
Scene scene
void EIG_linear_solver_variable_set(LinearSolver *solver, int rhs, int index, double value)
void EIG_linear_solver_right_hand_side_add(LinearSolver *solver, int rhs, int index, double value)
LinearSolver * EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_rhs)
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_freeN)(void *vmemh)
Definition: mallocn.c:27
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
Definition: mallocn.c:32
void *(* MEM_callocN)(size_t len, const char *str)
Definition: mallocn.c:31
ccl_device_inline float3 pow(float3 v, float e)
Definition: math_float3.h:533
#define fabsf(x)
Definition: metal/compat.h:219
LinearSolver * context
const MEdge * medges
float(* fweights)[3]
Definition: meshlaplacian.c:68
LinearSolver * context
Definition: meshlaplacian.c:60
unsigned int v
struct MEdge * medge
int totedge
struct MLoop * mloop
int totpoly
int totloop
struct MPoly * mpoly
struct Object * object
Definition: BKE_modifier.h:141
struct uiLayout * layout
ccl_device_inline float beta(float x, float y)
Definition: util/math.h:775
#define N_(msgid)
PointerRNA * ptr
Definition: wm_files.c:3480