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);
580 memcpy(lmd->
vertexco, vertexCos,
sizeof(
float[3]) * verts_num);
584 mesh->
verts_num, corner_tris, corner_verts, &sys->ringf_map, &sys->ringf_indices);
587 for (
i = 0;
i < sys->tris_num;
i++) {
588 sys->tris[
i][0] = corner_verts[corner_tris[
i][0]];
589 sys->tris[
i][1] = corner_verts[corner_tris[
i][1]];
590 sys->tris[
i][2] = corner_verts[corner_tris[
i][2]];
623 for (
i = 0;
i < verts_num;
i++) {
631 if (sys->anchors_num != anchors_num) {
641 float (*filevertexCos)[3];
644 filevertexCos =
nullptr;
661 memcpy(filevertexCos, lmd->
vertexco,
sizeof(
float[3]) * verts_num);
666 initSystem(lmd, ob, mesh, filevertexCos, verts_num);
676 ob, &lmd->
modifier,
"Vertices changed from %d to %d", lmd->
verts_num, verts_num);
680 ob, &lmd->
modifier,
"Edges changed from %d to %d", sys->edges_num, mesh->
edges_num);
685 "Vertex group '%s' is not valid, or maybe empty",
686 sys->anchor_grp_name);
691 sys->repeat = lmd->
repeat;
699 "Vertex group '%s' is not valid, or maybe empty",
705 memcpy(filevertexCos, lmd->
vertexco,
sizeof(
float[3]) * verts_num);
708 initSystem(lmd, ob, mesh, filevertexCos, verts_num);
714 initSystem(lmd, ob, mesh, vertexCos, verts_num);
719 if (sys && sys->is_matrix_computed && !sys->has_solution) {
771 reinterpret_cast<float (*)[3]
>(positions.
data()),
805 row = &layout->
row(
true);
808 "OBJECT_OT_laplaciandeform_bind", is_bind ?
IFACE_(
"Unbind") :
IFACE_(
"Bind"), ICON_NONE);
838 BLO_write_float3_array(writer, lmd.verts_num, lmd.vertexco);
851 BLO_read_float3_array(reader, lmd->verts_num, &lmd->vertexco);
852 return blender::implicit_sharing::info_for_mem_free(lmd->vertexco);
860 N_(
"LaplacianDeform"),
861 "LaplacianDeformModifierData",
863 &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)
bool BLO_write_is_undo(BlendWriter *writer)
void BLO_write_shared(BlendWriter *writer, const void *data, size_t approximate_size_in_bytes, const blender::ImplicitSharingInfo *sharing_info, blender::FunctionRef< void()> write_fn)
const blender::ImplicitSharingInfo * BLO_read_shared(BlendDataReader *reader, T **data_ptr, blender::FunctionRef< const blender::ImplicitSharingInfo *()> read_fn)
#define BLO_write_struct_at_address(writer, struct_name, address, data_ptr)
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define CD_MASK_MDEFORMVERT
#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)
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
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_freeN(void *vmemh)
ccl_device_inline float beta(const float x, const float y)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
const ImplicitSharingInfo * info_for_mem_free(void *data)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
VecBase< int32_t, 3 > int3
int RNA_string_length(PointerRNA *ptr, const char *name)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
void enabled_set(bool enabled)
uiLayout & row(bool align)
PointerRNA op(wmOperatorType *ot, std::optional< blender::StringRef > name, int icon, blender::wm::OpCallContext context, eUI_Item_Flag flag)
void use_property_split_set(bool value)
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)