27#include "RNA_prototypes.hh"
77 memset(sys->
eweights, val,
sizeof(
float) * sys->
edges.size());
93 sys->
eweights = MEM_cnew_array<float>(a_numEdges, __func__);
94 sys->
fweights = MEM_cnew_array<float[3]>(a_numLoops, __func__);
106 float (*vertexCos)[3],
112 for (
const int i : faces.index_range()) {
114 int corner_first = face.
start();
115 int corner_prev = corner_first + 1;
116 int corner_curr = corner_first + 2;
117 int corner_term = corner_first + face.size();
119 for (; corner_curr != corner_term; corner_prev = corner_curr, corner_curr++) {
121 vertexCos[corner_verts[corner_first]],
122 vertexCos[corner_verts[corner_prev]],
123 vertexCos[corner_verts[corner_curr]]);
136 beta =
pow(vini / vend, 1.0f / 3.0f);
162 for (i = 0; i < sys->
edges.size(); i++) {
163 idv1 = sys->
edges[i][0];
164 idv2 = sys->
edges[i][1];
172 if (w1 < sys->min_area) {
185 for (
const int i : sys->
faces.index_range()) {
187 int corner_next = face.start();
188 int corner_term = corner_next + face.size();
189 int corner_prev = corner_term - 2;
190 int corner_curr = corner_term - 1;
192 for (; corner_next != corner_term;
193 corner_prev = corner_curr, corner_curr = corner_next, corner_next++)
195 const float *v_prev = sys->
vertexCos[corner_verts[corner_prev]];
196 const float *v_curr = sys->
vertexCos[corner_verts[corner_curr]];
197 const float *v_next = sys->
vertexCos[corner_verts[corner_next]];
199 sys->
ne_fa_num[corner_verts[corner_curr]] += 1;
203 if (areaf < sys->min_area) {
204 sys->
zerola[corner_verts[corner_curr]] =
true;
207 sys->
ring_areas[corner_verts[corner_prev]] += areaf;
208 sys->
ring_areas[corner_verts[corner_curr]] += areaf;
209 sys->
ring_areas[corner_verts[corner_next]] += areaf;
215 sys->
fweights[corner_curr][0] += w1;
216 sys->
fweights[corner_curr][1] += w2;
217 sys->
fweights[corner_curr][2] += w3;
219 sys->
vweights[corner_verts[corner_curr]] += w2 + w3;
220 sys->
vweights[corner_verts[corner_next]] += w1 + w3;
221 sys->
vweights[corner_verts[corner_prev]] += w1 + w2;
224 for (i = 0; i < sys->
edges.size(); i++) {
225 idv1 = sys->
edges[i][0];
226 idv2 = sys->
edges[i][1];
244 for (
const int i : sys->
faces.index_range()) {
246 int corner_next = face.start();
247 int corner_term = corner_next + face.size();
248 int corner_prev = corner_term - 2;
249 int corner_curr = corner_term - 1;
251 for (; corner_next != corner_term;
252 corner_prev = corner_curr, corner_curr = corner_next, corner_next++)
256 if (sys->
ne_ed_num[corner_verts[corner_curr]] == sys->
ne_fa_num[corner_verts[corner_curr]] &&
257 sys->
zerola[corner_verts[corner_curr]] ==
false)
260 corner_verts[corner_curr],
261 corner_verts[corner_next],
263 sys->
vweights[corner_verts[corner_curr]]);
265 corner_verts[corner_curr],
266 corner_verts[corner_prev],
268 sys->
vweights[corner_verts[corner_curr]]);
270 if (sys->
ne_ed_num[corner_verts[corner_next]] == sys->
ne_fa_num[corner_verts[corner_next]] &&
271 sys->
zerola[corner_verts[corner_next]] ==
false)
274 corner_verts[corner_next],
275 corner_verts[corner_curr],
277 sys->
vweights[corner_verts[corner_next]]);
279 corner_verts[corner_next],
280 corner_verts[corner_prev],
282 sys->
vweights[corner_verts[corner_next]]);
284 if (sys->
ne_ed_num[corner_verts[corner_prev]] == sys->
ne_fa_num[corner_verts[corner_prev]] &&
285 sys->
zerola[corner_verts[corner_prev]] ==
false)
288 corner_verts[corner_prev],
289 corner_verts[corner_curr],
291 sys->
vweights[corner_verts[corner_prev]]);
293 corner_verts[corner_prev],
294 corner_verts[corner_next],
296 sys->
vweights[corner_verts[corner_prev]]);
301 for (i = 0; i < sys->
edges.size(); i++) {
302 idv1 = sys->
edges[i][0];
303 idv2 = sys->
edges[i][1];
307 sys->
zerola[idv2] ==
false)
321 float vini = 0.0f, vend = 0.0f;
327 if (sys->
zerola[i] ==
false) {
329 (lambda_border >= 0.0f ? 1.0f : -1.0f);
366 sys->
edges = mesh->edges();
367 sys->
faces = mesh->faces();
382 for (iter = 0; iter < smd->
repeat; iter++) {
383 for (i = 0; i < verts_num; i++) {
391 if (iter == 0 && verts_num > 0) {
396 for (i = 0; i < verts_num; i++) {
410 if (sys->
zerola[i] ==
false) {
502 if (positions.is_empty()) {
509 reinterpret_cast<float(*)[3]
>(positions.data()),
527 uiItemR(row,
ptr,
"use_x", toggles_flag,
nullptr, ICON_NONE);
528 uiItemR(row,
ptr,
"use_y", toggles_flag,
nullptr, ICON_NONE);
529 uiItemR(row,
ptr,
"use_z", toggles_flag,
nullptr, ICON_NONE);
549 N_(
"LaplacianSmooth"),
550 "LaplacianSmoothModifierData",
552 &RNA_LaplacianSmoothModifier,
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
float area_tri_v3(const float v1[3], const float v2[3], const float v3[3])
float volume_tetrahedron_signed_v3(const float v1[3], const float v2[3], const float v3[3], const float v4[3])
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
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])
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
struct LaplacianSmoothModifierData LaplacianSmoothModifierData
@ eModifierType_LaplacianSmooth
@ MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME
@ MOD_LAPLACIANSMOOTH_NORMALIZED
@ MOD_LAPLACIANSMOOTH_INVERT_VGROUP
Read Guarded memory(de)allocation.
static void init_data(ModifierData *md)
static void deform_verts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, blender::MutableSpan< blender::float3 > positions)
static void panel_register(ARegionType *region_type)
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 LaplacianSystem * init_laplacian_system(int a_numEdges, int a_numLoops, int a_numVerts)
static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag)
static void memset_laplacian_system(LaplacianSystem *sys, int val)
static void panel_draw(const bContext *, Panel *panel)
static void required_data_mask(ModifierData *md, CustomData_MeshMasks *r_cddata_masks)
static void validate_solution(LaplacianSystem *sys, short flag, float lambda, float lambda_border)
static void fill_laplacian_matrix(LaplacianSystem *sys)
static float compute_volume(const float center[3], float(*vertexCos)[3], const blender::OffsetIndices< int > faces, const blender::Span< int > corner_verts)
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
PanelType * modifier_panel_register(ARegionType *region_type, ModifierType type, PanelDrawFn draw)
PointerRNA * modifier_panel_get_property_pointers(Panel *panel, PointerRNA *r_ob_ptr)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
@ UI_ITEM_R_FORCE_BLANK_DECORATE
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE const btScalar & w() const
Return the w value.
constexpr int64_t start() const
constexpr int64_t size() const
pow(value.r - subtrahend, 2.0)") .do_static_compilation(true)
draw_view in_light_buf[] float
LinearSolver * EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_rhs)
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)
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)
void *(* MEM_callocN)(size_t len, const char *str)
blender::OffsetIndices< int > faces
blender::Span< int > corner_verts
blender::Span< blender::int2 > edges
ccl_device_inline float beta(float x, float y)