24#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE 1.8f
25#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE 0.15f
56 LaplacianSystem *sys,
int usex,
int usey,
int usez,
int preserve_volume);
58 BMOperator *op,
float vini,
float vend,
int usex,
int usey,
int usez);
85 memset(sys->eweights, val,
sizeof(
float) * sys->numEdges);
86 memset(sys->
fweights, val,
sizeof(
float[3]) * sys->numLoops);
87 memset(sys->ring_areas, val,
sizeof(
float) * sys->numVerts);
88 memset(sys->vlengths, val,
sizeof(
float) * sys->numVerts);
89 memset(sys->vweights, val,
sizeof(
float) * sys->numVerts);
90 memset(sys->zerola, val,
sizeof(
bool) * sys->numVerts);
97 sys->numEdges = a_numEdges;
98 sys->numLoops = a_numLoops;
99 sys->numVerts = a_numVerts;
102 if (!sys->eweights) {
107 sys->
fweights =
static_cast<float (*)[3]
>(
108 MEM_callocN(
sizeof(
float[3]) * sys->numLoops,
"ModLaplSmoothFWeight"));
110 delete_laplacian_system(sys);
115 if (!sys->ring_areas) {
116 delete_laplacian_system(sys);
121 if (!sys->vlengths) {
122 delete_laplacian_system(sys);
127 if (!sys->vweights) {
128 delete_laplacian_system(sys);
134 delete_laplacian_system(sys);
170 const float *v1 =
e->v1->co;
171 const float *
v2 =
e->v2->co;
176 if (w1 > sys->min_area) {
178 sys->eweights[
i] = w1;
179 sys->vlengths[idv1] += w1;
180 sys->vlengths[idv2] += w1;
183 sys->zerola[idv1] =
true;
184 sys->zerola[idv2] =
true;
188 uint l_curr_index = 0;
192 l_curr_index += f->
len;
205 const float *co_prev = l_iter->
prev->
v->
co;
206 const float *co_curr = l_iter->
v->
co;
207 const float *co_next = l_iter->
next->
v->
co;
209 const float areaf =
area_tri_v3(co_prev, co_curr, co_next);
211 if (areaf < sys->min_area) {
212 sys->zerola[vi_curr] =
true;
215 sys->ring_areas[vi_prev] += areaf;
216 sys->ring_areas[vi_curr] += areaf;
217 sys->ring_areas[vi_next] += areaf;
223 sys->
fweights[l_curr_index][0] += w1;
224 sys->
fweights[l_curr_index][1] += w2;
225 sys->
fweights[l_curr_index][2] += w3;
227 sys->vweights[vi_prev] += w1 + w2;
228 sys->vweights[vi_curr] += w2 + w3;
229 sys->vweights[vi_next] += w1 + w3;
230 }
while ((
void)(l_curr_index += 1), (l_iter = l_iter->
next) != l_first);
242 uint l_curr_index = 0;
246 l_curr_index += f->
len;
267 sys->
fweights[l_curr_index][1] * sys->vweights[vi_prev]);
271 sys->
fweights[l_curr_index][0] * sys->vweights[vi_prev]);
277 sys->
fweights[l_curr_index][2] * sys->vweights[vi_curr]);
281 sys->
fweights[l_curr_index][1] * sys->vweights[vi_curr]);
287 sys->
fweights[l_curr_index][2] * sys->vweights[vi_next]);
291 sys->
fweights[l_curr_index][0] * sys->vweights[vi_next]);
300 }
while ((
void)(l_curr_index += 1), (l_iter = l_iter->
next) != l_first);
308 if (sys->zerola[idv1] ==
false && sys->zerola[idv2] ==
false) {
310 sys->
context, idv1, idv2, sys->eweights[
i] * sys->vlengths[idv1]);
312 sys->
context, idv2, idv1, sys->eweights[
i] * sys->vlengths[idv2]);
337 BMOperator *op,
float vini,
float vend,
int usex,
int usey,
int usez)
344 beta =
pow(vini / vend, 1.0f / 3.0f);
360 LaplacianSystem *sys,
int usex,
int usey,
int usez,
int preserve_volume)
365 float *vi1, *vi2, ve1[3], ve2[3];
388 sys->zerola[idv1] =
true;
389 sys->zerola[idv2] =
true;
393 if (preserve_volume) {
398 if (sys->zerola[m_vertex_id] ==
false) {
410 if (preserve_volume) {
420 bool usex, usey, usez, preserve_volume;
421 float lambda_factor, lambda_border;
427 if (
bm->totface == 0) {
442 sys->min_area = 0.00001f;
450 for (
i = 0;
i <
bm->totvert;
i++) {
468 if ((sys->zerola[
i] ==
false) &&
471 (sys->ring_areas[
i] != 0.0f))
473 w = sys->vweights[
i] * sys->ring_areas[
i];
474 sys->vweights[
i] = (
w == 0.0f) ? 0.0f : -lambda_factor / (4.0f *
w);
475 w = sys->vlengths[
i];
476 sys->vlengths[
i] = (
w == 0.0f) ? 0.0f : -lambda_border * 2.0f /
w;
480 sys->
context,
i,
i, 1.0f + lambda_factor / (4.0f * sys->ring_areas[
i]));
float area_tri_v3(const float v1[3], const float v2[3], const float v3[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
Read Guarded memory(de)allocation.
#define BM_FACE_FIRST_LOOP(p)
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
#define BM_ITER_MESH(ele, iter, bm, itype)
#define BM_ITER_MESH_INDEX(ele, iter, bm, itype, indexvar)
BMesh const char void * data
void BM_mesh_elem_index_ensure(BMesh *bm, const char htype)
float BMO_slot_float_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
#define BMO_ITER(ele, iter, slot_args, slot_name, restrict_flag)
bool BMO_slot_bool_get(BMOpSlot slot_args[BMO_OP_MAX_SLOTS], const char *slot_name)
double BM_mesh_calc_volume(BMesh *bm, bool is_signed)
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static void delete_void_pointer(void *data)
void bmo_smooth_laplacian_vert_exec(BMesh *bm, BMOperator *op)
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 bool vert_is_boundary(BMVert *v)
static void validate_solution(LaplacianSystem *sys, int usex, int usey, int usez, int preserve_volume)
#define SMOOTH_LAPLACIAN_MAX_EDGE_PERCENTAGE
static void memset_laplacian_system(LaplacianSystem *sys, int val)
#define SMOOTH_LAPLACIAN_MIN_EDGE_PERCENTAGE
static void volume_preservation(BMOperator *op, float vini, float vend, int usex, int usey, int usez)
static void fill_laplacian_matrix(LaplacianSystem *sys)
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)
void EIG_linear_solver_variable_unlock(LinearSolver *solver, int index)
LinearSolver * EIG_linear_least_squares_solver_new(int num_rows, int num_columns, int num_right_hand_sides)
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 EIG_linear_solver_variable_lock(LinearSolver *solver, int index)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void MEM_freeN(void *vmemh)
ccl_device_inline float beta(const float x, const float y)
struct BMOpSlot slots_in[BMO_OP_MAX_SLOTS]