117 sys->vertexCos =
NULL;
126 memset(sys->eweights, val,
sizeof(
float) * sys->numEdges);
127 memset(sys->
fweights, val,
sizeof(
float[3]) * sys->numLoops);
128 memset(sys->numNeEd, val,
sizeof(
short) * sys->numVerts);
129 memset(sys->numNeFa, val,
sizeof(
short) * sys->numVerts);
130 memset(sys->ring_areas, val,
sizeof(
float) * sys->numVerts);
131 memset(sys->vlengths, val,
sizeof(
float) * sys->numVerts);
132 memset(sys->vweights, val,
sizeof(
float) * sys->numVerts);
133 memset(sys->zerola, val,
sizeof(
short) * sys->numVerts);
143 sys->numEdges = a_numEdges;
144 sys->numPolys = a_numPolys;
145 sys->numLoops = a_numLoops;
146 sys->numVerts = a_numVerts;
172 const MLoop *l_prev = l_first + 1;
173 const MLoop *l_curr = l_first + 2;
176 for (; l_curr != l_term; l_prev = l_curr, l_curr++) {
191 beta =
pow(vini / vend, 1.0f / 3.0f);
192 for (i = 0; i < sys->numVerts; i++) {
194 sys->vertexCos[i][0] = (sys->vertexCos[i][0] - sys->vert_centroid[0]) *
beta +
195 sys->vert_centroid[0];
198 sys->vertexCos[i][1] = (sys->vertexCos[i][1] - sys->vert_centroid[1]) *
beta +
199 sys->vert_centroid[1];
202 sys->vertexCos[i][2] = (sys->vertexCos[i][2] - sys->vert_centroid[2]) *
beta +
203 sys->vert_centroid[2];
217 for (i = 0; i < sys->numEdges; i++) {
218 idv1 = sys->medges[i].v1;
219 idv2 = sys->medges[i].v2;
221 v1 = sys->vertexCos[idv1];
222 v2 = sys->vertexCos[idv2];
224 sys->numNeEd[idv1] = sys->numNeEd[idv1] + 1;
225 sys->numNeEd[idv2] = sys->numNeEd[idv2] + 1;
228 sys->zerola[idv1] = 1;
229 sys->zerola[idv2] = 1;
235 sys->eweights[i] = w1;
238 for (i = 0; i < sys->numPolys; i++) {
239 const MPoly *mp = &sys->mpoly[i];
242 const MLoop *l_prev = l_term - 2;
243 const MLoop *l_curr = l_term - 1;
245 for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
246 const float *v_prev = sys->vertexCos[l_prev->
v];
247 const float *v_curr = sys->vertexCos[l_curr->
v];
248 const float *v_next = sys->vertexCos[l_next->
v];
249 const uint l_curr_index = l_curr - sys->mloop;
251 sys->numNeFa[l_curr->
v] += 1;
256 sys->zerola[l_curr->
v] = 1;
259 sys->ring_areas[l_prev->
v] += areaf;
260 sys->ring_areas[l_curr->
v] += areaf;
261 sys->ring_areas[l_next->
v] += areaf;
267 sys->
fweights[l_curr_index][0] += w1;
268 sys->
fweights[l_curr_index][1] += w2;
269 sys->
fweights[l_curr_index][2] += w3;
271 sys->vweights[l_curr->
v] += w2 + w3;
272 sys->vweights[l_next->
v] += w1 + w3;
273 sys->vweights[l_prev->
v] += w1 + w2;
276 for (i = 0; i < sys->numEdges; i++) {
277 idv1 = sys->medges[i].v1;
278 idv2 = sys->medges[i].v2;
280 if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2]) {
281 sys->vlengths[idv1] += sys->eweights[i];
282 sys->vlengths[idv2] += sys->eweights[i];
292 for (i = 0; i < sys->numPolys; i++) {
293 const MPoly *mp = &sys->mpoly[i];
296 const MLoop *l_prev = l_term - 2;
297 const MLoop *l_curr = l_term - 1;
299 for (; l_next != l_term; l_prev = l_curr, l_curr = l_next, l_next++) {
300 const uint l_curr_index = l_curr - sys->mloop;
303 if (sys->numNeEd[l_curr->
v] == sys->numNeFa[l_curr->
v] && sys->zerola[l_curr->
v] == 0) {
307 sys->
fweights[l_curr_index][2] * sys->vweights[l_curr->
v]);
311 sys->
fweights[l_curr_index][1] * sys->vweights[l_curr->
v]);
313 if (sys->numNeEd[l_next->
v] == sys->numNeFa[l_next->
v] && sys->zerola[l_next->
v] == 0) {
317 sys->
fweights[l_curr_index][2] * sys->vweights[l_next->
v]);
321 sys->
fweights[l_curr_index][0] * sys->vweights[l_next->
v]);
323 if (sys->numNeEd[l_prev->
v] == sys->numNeFa[l_prev->
v] && sys->zerola[l_prev->
v] == 0) {
327 sys->
fweights[l_curr_index][1] * sys->vweights[l_prev->
v]);
331 sys->
fweights[l_curr_index][0] * sys->vweights[l_prev->
v]);
336 for (i = 0; i < sys->numEdges; i++) {
337 idv1 = sys->medges[i].v1;
338 idv2 = sys->medges[i].v2;
340 if (sys->numNeEd[idv1] != sys->numNeFa[idv1] && sys->numNeEd[idv2] != sys->numNeFa[idv2] &&
341 sys->zerola[idv1] == 0 && sys->zerola[idv2] == 0) {
343 sys->
context, idv1, idv2, sys->eweights[i] * sys->vlengths[idv1]);
345 sys->
context, idv2, idv1, sys->eweights[i] * sys->vlengths[idv2]);
354 float vini = 0.0f, vend = 0.0f;
358 sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
360 for (i = 0; i < sys->numVerts; i++) {
361 if (sys->zerola[i] == 0) {
362 lam = sys->numNeEd[i] == sys->numNeFa[i] ? (lambda >= 0.0f ? 1.0f : -1.0f) :
363 (lambda_border >= 0.0f ? 1.0f : -1.0f);
366 sys->vertexCos[i][0]);
370 sys->vertexCos[i][1]);
374 sys->vertexCos[i][2]);
380 sys->vert_centroid, sys->vertexCos, sys->mpoly, sys->numPolys, sys->mloop);
405 sys->min_area = 0.00001f;
408 sys->vert_centroid[0] = 0.0f;
409 sys->vert_centroid[1] = 0.0f;
410 sys->vert_centroid[2] = 0.0f;
417 for (iter = 0; iter < smd->
repeat; iter++) {
445 if (sys->zerola[i] == 0) {
447 w = sys->vweights[i];
448 sys->vweights[i] = (
w == 0.0f) ? 0.0f : -
fabsf(smd->
lambda) * wpaint /
w;
449 w = sys->vlengths[i];
451 if (sys->numNeEd[i] == sys->numNeFa[i]) {
460 w = sys->vweights[i] * sys->ring_areas[i];
461 sys->vweights[i] = (
w == 0.0f) ? 0.0f : -
fabsf(smd->
lambda) * wpaint / (4.0f *
w);
462 w = sys->vlengths[i];
465 if (sys->numNeEd[i] == sys->numNeFa[i]) {
470 (4.0f * sys->ring_areas[i]));
509 bool UNUSED(useRenderParams))
574 if (mesh_src !=
NULL) {
622 "LaplacianSmoothModifierData",
typedef float(TangentPoint)[2]
void BKE_id_free(struct Main *bmain, void *idv)
void BKE_mesh_wrapper_ensure_mdata(struct Mesh *me)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
void BKE_modifier_copydata_generic(const struct ModifierData *md, struct ModifierData *md_dst, const int flag)
@ eModifierTypeType_OnlyDeform
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)
@ MOD_LAPLACIANSMOOTH_PRESERVE_VOLUME
@ MOD_LAPLACIANSMOOTH_NORMALIZED
@ 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.
static void deformVertsEM(ModifierData *md, const ModifierEvalContext *ctx, struct BMEditMesh *editData, Mesh *mesh, float(*vertexCos)[3], int numVerts)
static void init_data(ModifierData *md)
static bool is_disabled(const struct Scene *scene, ModifierData *md, bool useRenderParams)
static float compute_volume(const float center[3], float(*vertexCos)[3], const MPoly *mpoly, int numPolys, const MLoop *mloop)
ModifierTypeInfo modifierType_LaplacianSmooth
static void init_laplacian_matrix(LaplacianSystem *sys)
static void delete_laplacian_system(LaplacianSystem *sys)
static void deformVerts(ModifierData *md, const ModifierEvalContext *ctx, Mesh *mesh, float(*vertexCos)[3], int numVerts)
static void volume_preservation(LaplacianSystem *sys, float vini, float vend, short flag)
static void memset_laplacian_system(LaplacianSystem *sys, int val)
static void laplaciansmoothModifier_do(LaplacianSmoothModifierData *smd, Object *ob, Mesh *mesh, float(*vertexCos)[3], int numVerts)
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 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)
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 num_verts, const bool use_normals, const bool use_orco)
void MOD_get_vgroup(Object *ob, struct Mesh *mesh, const char *name, MDeformVert **dvert, int *defgrp_index)
StructRNA RNA_LaplacianSmoothModifier
uiLayout * uiLayoutRowWithHeading(uiLayout *layout, bool align, const char *heading)
@ UI_ITEM_R_FORCE_BLANK_DECORATE
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
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.
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)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_callocN)(size_t len, const char *str)
INLINE Rall1d< T, V, S > pow(const Rall1d< T, V, S > &arg, double m)
ccl_device_inline float beta(float x, float y)