34#include "RNA_prototypes.hh"
55 bool is_matrix_computed;
63 char anchor_grp_name[ 64];
87 MeshElemMap *ringf_map;
89 MeshElemMap *ringv_map;
98 sys->is_matrix_computed =
false;
99 sys->has_solution =
false;
102 sys->anchors_num = 0;
105 sys->anchor_grp_name[0] =
'\0';
114 const char defgrpName[64],
119 sys->is_matrix_computed =
false;
120 sys->has_solution =
false;
122 sys->edges_num = edges_num;
123 sys->tris_num = tris_num;
124 sys->anchors_num = anchors_num;
125 sys->repeat = iterations;
126 STRNCPY(sys->anchor_grp_name, defgrpName);
167 for (
int j = 0; j < 3; j++) {
168 const int v_index = corner_verts[tri[j]];
169 map[v_index].
count++;
175 for (
int i = 0;
i < mvert_tot;
i++) {
177 index_iter += map[
i].
count;
182 for (
int j = 0; j < 3; j++) {
183 const int v_index = corner_verts[tri[j]];
185 map[v_index].
count++;
198 int i, vid[2], indices_num = 0;
202 vid[0] = edges[
i][0];
203 vid[1] = edges[
i][1];
210 for (
i = 0;
i < mvert_tot;
i++) {
212 index_iter += map[
i].
count;
216 vid[0] = edges[
i][0];
217 vid[1] = edges[
i][1];
266 for (ti = 0; ti < sys->tris_num; ti++) {
267 const uint *vidt = sys->tris[ti];
270 co[0] = sys->co[vidt[0]];
271 co[1] = sys->co[vidt[1]];
272 co[2] = sys->co[vidt[2]];
279 for (j = 0; j < 3; j++) {
280 const float *v1, *
v2, *v3;
283 idv[1] = vidt[(j + 1) %
i];
284 idv[2] = vidt[(j + 2) %
i];
286 v1 = sys->co[idv[0]];
287 v2 = sys->co[idv[1]];
288 v3 = sys->co[idv[2]];
293 sys->delta[idv[0]][0] += v1[0] * (w2 + w3);
294 sys->delta[idv[0]][1] += v1[1] * (w2 + w3);
295 sys->delta[idv[0]][2] += v1[2] * (w2 + w3);
297 sys->delta[idv[0]][0] -=
v2[0] * w2;
298 sys->delta[idv[0]][1] -=
v2[1] * w2;
299 sys->delta[idv[0]][2] -=
v2[2] * w2;
301 sys->delta[idv[0]][0] -= v3[0] * w3;
302 sys->delta[idv[0]][1] -= v3[1] * w3;
303 sys->delta[idv[0]][2] -= v3[2] * w3;
314 int vid, *vidn =
nullptr;
315 float minj, mjt, qj[3], vj[3];
320 vidn = sys->ringv_map[
i].indices;
321 ln = sys->ringv_map[
i].count;
323 for (j = 0; j < ln; j++) {
331 sys->unit_verts[
i] = vidn[j];
339 float alpha,
beta, gamma;
340 float pj[3], ni[3], di[3];
341 float uij[3], dun[3], e2[3], pi[3], fni[3], vn[3][3];
342 int i, j, fidn_num, k, fi;
348 k = sys->unit_verts[
i];
364 fidn_num = sys->ringf_map[
i].count;
365 for (fi = 0; fi < fidn_num; fi++) {
367 fidn = sys->ringf_map[
i].indices;
368 vin = sys->tris[fidn[fi]];
369 for (j = 0; j < 3; j++) {
373 if (vin[j] == sys->unit_verts[
i]) {
388 fni[0] = alpha * ni[0] +
beta * uij[0] + gamma * e2[0];
389 fni[1] = alpha * ni[1] +
beta * uij[1] + gamma * e2[1];
390 fni[2] = alpha * ni[2] +
beta * uij[2] + gamma * e2[2];
407 int vid,
i, j, n, na;
409 na = sys->anchors_num;
411 if (!sys->is_matrix_computed) {
414 for (
i = 0;
i < n;
i++) {
419 for (
i = 0;
i < na;
i++) {
420 vid = sys->index_anchors[
i];
429 for (
i = 0;
i < n;
i++) {
434 for (
i = 0;
i < na;
i++) {
435 vid = sys->index_anchors[
i];
442 sys->has_solution =
true;
444 for (j = 1; j <= sys->repeat; j++) {
447 for (
i = 0;
i < na;
i++) {
448 vid = sys->index_anchors[
i];
455 sys->has_solution =
false;
459 if (sys->has_solution) {
460 for (vid = 0; vid < sys->
verts_num; vid++) {
467 sys->has_solution =
false;
471 sys->has_solution =
false;
473 sys->is_matrix_computed =
true;
475 else if (sys->has_solution) {
476 for (
i = 0;
i < n;
i++) {
481 for (
i = 0;
i < na;
i++) {
482 vid = sys->index_anchors[
i];
490 sys->has_solution =
true;
491 for (j = 1; j <= sys->repeat; j++) {
494 for (
i = 0;
i < na;
i++) {
495 vid = sys->index_anchors[
i];
501 sys->has_solution =
false;
505 if (sys->has_solution) {
506 for (vid = 0; vid < sys->
verts_num; vid++) {
513 sys->has_solution =
false;
517 sys->has_solution =
false;
529 return (dvert !=
nullptr);
554 for (
i = 0;
i < verts_num;
i++) {
575 memcpy(sys->index_anchors, index_anchors,
sizeof(
int) * anchors_num);
576 memcpy(sys->co, vertexCos,
sizeof(
float[3]) * verts_num);
579 memcpy(lmd->
vertexco, vertexCos,
sizeof(
float[3]) * verts_num);
583 mesh->
verts_num, corner_tris, corner_verts, &sys->ringf_map, &sys->ringf_indices);
586 for (
i = 0;
i < sys->tris_num;
i++) {
587 sys->tris[
i][0] = corner_verts[corner_tris[
i][0]];
588 sys->tris[
i][1] = corner_verts[corner_tris[
i][1]];
589 sys->tris[
i][2] = corner_verts[corner_tris[
i][2]];
622 for (
i = 0;
i < verts_num;
i++) {
630 if (sys->anchors_num != anchors_num) {
640 float(*filevertexCos)[3];
643 filevertexCos =
nullptr;
660 memcpy(filevertexCos, lmd->
vertexco,
sizeof(
float[3]) * verts_num);
665 initSystem(lmd, ob, mesh, filevertexCos, verts_num);
675 ob, &lmd->
modifier,
"Vertices changed from %d to %d", lmd->
verts_num, verts_num);
679 ob, &lmd->
modifier,
"Edges changed from %d to %d", sys->edges_num, mesh->
edges_num);
684 "Vertex group '%s' is not valid, or maybe empty",
685 sys->anchor_grp_name);
690 sys->repeat = lmd->
repeat;
698 "Vertex group '%s' is not valid, or maybe empty",
704 memcpy(filevertexCos, lmd->
vertexco,
sizeof(
float[3]) * verts_num);
707 initSystem(lmd, ob, mesh, filevertexCos, verts_num);
713 initSystem(lmd, ob, mesh, vertexCos, verts_num);
718 if (sys && sys->is_matrix_computed && !sys->has_solution) {
769 reinterpret_cast<float(*)[3]
>(positions.
data()),
803 row = &layout->
row(
true);
806 "OBJECT_OT_laplaciandeform_bind", is_bind ?
IFACE_(
"Unbind") :
IFACE_(
"Bind"), ICON_NONE);
849 N_(
"LaplacianDeform"),
850 "LaplacianDeformModifierData",
852 &RNA_LaplacianDeformModifier,
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
float cotangent_tri_weight_v3(const float v1[3], const float v2[3], const float v3[3])
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE float len_squared_v3(const float v[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void copy_v3_v3(float r[3], const float a[3])
MINLINE float dot_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void zero_v3(float r[3])
MINLINE void mul_v3_v3fl(float r[3], const float a[3], float f)
MINLINE void add_v3_v3(float r[3], const float a[3])
MINLINE float normalize_v3(float n[3])
char * STRNCPY(char(&dst)[N], const char *src)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
#define STACK_PUSH(stack, val)
#define STACK_DECLARE(stack)
#define STACK_SIZE(stack)
#define STACK_INIT(stack, stack_num)
void BLO_read_float3_array(BlendDataReader *reader, int64_t array_size, float **ptr_p)
void BLO_write_float3_array(BlendWriter *writer, int64_t num, const float *data_ptr)
bool BLO_write_is_undo(BlendWriter *writer)
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
#define DNA_struct_default_get(struct_name)
@ eModifierFlag_OverrideLibrary_Local
@ eModifierType_LaplacianDeform
@ MOD_LAPLACIANDEFORM_BIND
@ MOD_LAPLACIANDEFORM_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 required_data_mask(ModifierData *, CustomData_MeshMasks *r_cddata_masks)
static void blend_read(BlendDataReader *, ModifierData *md)
static void panel_draw(const bContext *, Panel *panel)
static void copy_data(const ModifierData *md, ModifierData *target, const int flag)
static void free_data(ModifierData *md)
static void blend_write(BlendWriter *writer, const ID *, const ModifierData *md)
void modifier_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const StringRefNull vgroup_prop, const std::optional< StringRefNull > invert_vgroup_prop, const std::optional< StringRefNull > text)
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_error_message_draw(uiLayout *layout, PointerRNA *ptr)
void MOD_get_vgroup(const Object *ob, const Mesh *mesh, const char *name, const MDeformVert **dvert, int *defgrp_index)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
constexpr int64_t size() const
constexpr T * data() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
#define CD_MASK_MDEFORMVERT
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
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_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 * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_callocN(size_t len, const char *str)
void * MEM_malloc_arrayN(size_t len, size_t size, const char *str)
void * MEM_dupallocN(const void *vmemh)
void MEM_freeN(void *vmemh)
ccl_device_inline float beta(const float x, const float y)
VecBase< int32_t, 3 > int3
int RNA_string_length(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, wmOperatorCallContext context, eUI_Item_Flag flag)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
uiLayout & row(bool align)
void prop(PointerRNA *ptr, PropertyRNA *prop, int index, int value, eUI_Item_Flag flag, std::optional< blender::StringRef > name_opt, int icon, std::optional< blender::StringRef > placeholder=std::nullopt)