34#include "RNA_prototypes.hh"
222 void delete_self_with_data()
override
224 for (
int i = 0;
i < this->bind_verts_num;
i++) {
225 if (this->verts[
i].binds) {
226 for (
int j = 0; j < this->verts[
i].
binds_num; j++) {
265 if (smd->
target !=
nullptr) {
291 for (
const int edge_i : corner_edges.
slice(polys[
i])) {
292 if (edge_polys[edge_i].
num == 0) {
293 edge_polys[edge_i].
polys[0] =
i;
294 edge_polys[edge_i].
polys[1] = -1;
295 edge_polys[edge_i].
num++;
297 else if (edge_polys[edge_i].
num == 1) {
298 edge_polys[edge_i].
polys[1] =
i;
299 edge_polys[edge_i].
num++;
312 vert_edges[edge[0]].
first = adj;
313 vert_edges[edge[0]].
num += edge_polys[
i].
num;
318 vert_edges[edge[1]].
first = adj;
319 vert_edges[edge[1]].
num += edge_polys[
i].
num;
327 const int *
const corner_verts,
328 const int *
const corner_edges,
334 for (
int i = 0;
i <
num;
i++) {
335 if (corner_edges[
i] == edge) {
345 for (
int i = 0; corner_edges[
i] != edge;
i++) {
352 const int *
const corner_verts,
353 const uint loopstart,
356 for (
int i = loopstart;
i <
num;
i++) {
361 for (
int i = 0;
i < loopstart;
i++) {
381 data->treeData->tree, t_point, &nearest,
data->treeData->nearest_callback,
data->treeData);
385 for (
int i = 0;
i < face.
size();
i++) {
386 const int edge_i =
data->corner_edges[face.
start() +
i];
389 point_co,
data->targetCos[edge[0]],
data->targetCos[edge[1]]);
391 if (dist < max_dist) {
409 float prev_co[2], prev_prev_co[2];
410 float curr_vec[2], prev_vec[2];
421 for (
int i = 0;
i < nr;
i++) {
426 if (curr_len < FLT_EPSILON) {
436 if (1.0f -
dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
470 const float point_co[3])
481 const float world[3] = {0.0f, 0.0f, 1.0f};
482 float avg_point_dist = 0.0f;
483 float tot_weight = 0.0f;
484 int inf_weight_flags = 0;
487 if (bwdata ==
nullptr) {
495 if (bpoly ==
nullptr) {
505 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
508 for (
int i = 0;
i < edge_polys[edge_ind].
num;
i++) {
512 for (
int j = 0; j < bwdata->
faces_num; bpoly++, j++) {
538 if (bpoly->
coords ==
nullptr) {
545 "SDefBindPolyCoords_v2");
552 for (
int j = 0; j < face.
size(); j++) {
553 const int vert_i =
data->corner_verts[face.
start() + j];
554 const int edge_i =
data->corner_edges[face.
start() + j];
558 if (vert_i == nearest) {
582 for (
int j = 0; j < face.
size(); j++) {
591 data->success = is_poly_valid;
629 float corner_angles[2];
642 if (bpoly->
scales[0] < FLT_EPSILON || bpoly->
scales[1] < FLT_EPSILON ||
661 float cent_point_vec[2], point_angles[2];
667 signf(corner_angles[0]);
669 signf(corner_angles[1]);
671 if (point_angles[0] <= 0 && point_angles[1] <= 0) {
674 if (point_angles[0] < point_angles[1]) {
718 if (!inf_weight_flags) {
719 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
722 float ang_weights[2];
724 uint edge_on_poly[2];
726 epolys = &edge_polys[edge_ind];
731 for (
int i = 0, j = 0; (
i < bwdata->
faces_num) && (j < epolys->
num); bpoly++,
i++) {
747 if (epolys->
num == 1) {
749 bpolys[0]->edgemid_angle);
752 else if (epolys->
num == 2) {
754 bpolys[0]->edgemid_angle);
756 bpolys[1]->edgemid_angle);
768 if (!inf_weight_flags) {
772 float corner_angle_weights[2];
773 float scale_weight,
sqr, inv_sqr;
778 if (
isnan(corner_angle_weights[0]) ||
isnan(corner_angle_weights[1])) {
785 if (corner_angle_weights[0] < corner_angle_weights[1]) {
810 scale_weight /= scale_weight + (edge_angle_b /
max_ff(edge_angle_b, bpoly->
edgemid_angle));
813 sqr = scale_weight * scale_weight;
814 inv_sqr = 1.0f - scale_weight;
816 scale_weight =
sqr / (
sqr + inv_sqr);
818 BLI_assert(scale_weight >= 0 && scale_weight <= 1);
888 tot_weight += bpoly->
weight;
894 bpoly->
weight /= tot_weight;
900 if (bpoly->
weight >= FLT_EPSILON) {
921 const float point_co_proj[3],
922 const float normal[3])
928 normal_dist =
len_v3(disp_vec);
930 if (
dot_v3v3(disp_vec, normal) < 0) {
943 float point_co_proj[3];
953 sdvert->
binds =
nullptr;
958 if (
data->sparse_bind) {
961 if (
data->dvert &&
data->defgrp_index != -1) {
965 if (
data->invert_vgroup) {
966 weight = 1.0f - weight;
970 sdvert->
binds =
nullptr;
979 if (bwdata ==
nullptr) {
980 sdvert->
binds =
nullptr;
986 if (sdvert->
binds ==
nullptr) {
994 sdbind = sdvert->
binds;
999 if (bpoly->
weight >= FLT_EPSILON) {
1006 "SDefNgonVertWeights");
1024 for (
int j = 0; j < bpoly->
verts_num; j++) {
1025 const int vert_i =
data->corner_verts[bpoly->
loopstart + j];
1037 float cent[3],
norm[3];
1038 float v1[3],
v2[3], v3[3];
1052 "SDefCentVertInds");
1156 new_verts[dst_index++] = smd->
verts[
i];
1162 smd->
verts = new_verts;
1170 float (*vertexCos)[3],
1172 uint target_faces_num,
1173 uint target_verts_num,
1193 if (vert_edges ==
nullptr) {
1200 if (adj_array ==
nullptr) {
1207 if (edge_polys ==
nullptr) {
1215 if (smd_orig->
verts ==
nullptr) {
1221 __func__, smd_orig->
verts, verts_num);
1224 if (treeData.
tree ==
nullptr) {
1231 adj_result =
buildAdjacencyMap(polys, edges, corner_edges, vert_edges, adj_array, edge_polys);
1235 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1252 data.treeData = &treeData;
1253 data.vert_edges = vert_edges;
1254 data.edge_polys = edge_polys;
1257 data.corner_verts = corner_verts;
1258 data.corner_edges = corner_edges;
1259 data.corner_tris = target->corner_tris();
1260 data.tri_faces = target->corner_tri_faces();
1262 "SDefTargetBindVertArray");
1264 data.vertexCos = vertexCos;
1268 data.defgrp_index = defgrp_index;
1269 data.invert_vgroup = invert_vgroup;
1270 data.sparse_bind = sparse_bind;
1272 if (
data.targetCos ==
nullptr) {
1280 for (
int i = 0;
i < target_verts_num;
i++) {
1304 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1331 return data.success == 1;
1339 const SDefBind *sdbind =
data->bind_verts[index].binds;
1340 const int sdbind_num =
data->bind_verts[index].binds_num;
1341 const uint vertex_idx =
data->bind_verts[index].vertex_idx;
1342 float *
const vertexCos =
data->vertexCos[vertex_idx];
1343 float norm[3], temp[3], offset[3];
1346 float weight = 1.0f;
1348 if (
data->dvert &&
data->defgrp_index != -1) {
1351 if (
data->invert_vgroup) {
1352 weight = 1.0f - weight;
1358 if (weight == 0.0f) {
1365 for (
int j = 0; j < sdbind_num; j++) {
1366 max_verts = std::max(max_verts,
int(sdbind[j].verts_num));
1372 for (
int j = 0; j < sdbind_num; j++, sdbind++) {
1373 for (
int k = 0; k < sdbind->
verts_num; k++) {
1378 norm,
reinterpret_cast<const float (*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1381 switch (sdbind->
mode) {
1392 for (
int k = 0; k < sdbind->
verts_num; k++) {
1402 cent,
reinterpret_cast<const float (*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1425 float (*vertexCos)[3],
1432 uint target_verts_num, target_faces_num;
1436 if (smd->
verts !=
nullptr) {
1458 if (smd->
verts ==
nullptr) {
1466 float tmp_mat[4][4];
1469 mul_m4_m4m4(smd_orig->
mat, tmp_mat, ob_target->object_to_world().ptr());
1493 ob, md,
"Vertices changed from %u to %u", smd->
mesh_verts_num, verts_num);
1503 ob, md,
"Target polygons changed from %u to %u", smd->
target_polys_num, target_faces_num);
1511 "Target vertices changed from %u to %u",
1523 "Target vertices changed from %u to %u, continuing anyway",
1547 data.vertexCos = vertexCos;
1549 data.defgrp_index = defgrp_index;
1550 data.invert_vgroup = invert_vgroup;
1553 if (
data.targetCos !=
nullptr) {
1555 target,
data.targetCos, target_verts_num, smd->
mat);
1573 reinterpret_cast<float (*)[3]
>(positions.
data()),
1607 col->active_set(!is_bound);
1616 col->enabled_set(!is_bound);
1624 col->op(
"OBJECT_OT_surfacedeform_bind",
IFACE_(
"Unbind"), ICON_NONE);
1628 col->op(
"OBJECT_OT_surfacedeform_bind",
IFACE_(
"Bind"), ICON_NONE);
1650 smd.
verts =
nullptr;
1655 if (smd.
verts !=
nullptr) {
1658 SDefVert *bind_verts = smd.verts;
1659 BLO_write_struct_array(writer, SDefVert, smd.bind_verts_num, bind_verts);
1661 for (int i = 0; i < smd.bind_verts_num; i++) {
1662 BLO_write_struct_array(writer, SDefBind, bind_verts[i].binds_num, bind_verts[i].binds);
1664 if (bind_verts[i].binds) {
1665 for (int j = 0; j < bind_verts[i].binds_num; j++) {
1666 BLO_write_uint32_array(
1667 writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_inds);
1669 if (ELEM(bind_verts[i].binds[j].mode,
1670 MOD_SDEF_MODE_CENTROID,
1671 MOD_SDEF_MODE_CORNER_TRIS))
1673 BLO_write_float3_array(writer, 1, bind_verts[i].binds[j].vert_weights);
1676 BLO_write_float_array(writer,
1677 bind_verts[i].binds[j].verts_num,
1678 bind_verts[i].binds[j].vert_weights);
1695 BLO_read_struct_array(reader, SDefVert, smd->bind_verts_num, &smd->verts);
1696 for (int i = 0; i < smd->bind_verts_num; i++) {
1697 BLO_read_struct_array(reader, SDefBind, smd->verts[i].binds_num, &smd->verts[i].binds);
1699 if (smd->verts[i].binds) {
1700 for (int j = 0; j < smd->verts[i].binds_num; j++) {
1701 BLO_read_uint32_array(
1702 reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_inds);
1704 if (ELEM(smd->verts[i].binds[j].mode,
1705 MOD_SDEF_MODE_CENTROID,
1706 MOD_SDEF_MODE_CORNER_TRIS))
1708 BLO_read_float3_array(reader, 1, &smd->verts[i].binds[j].vert_weights);
1711 BLO_read_float_array(
1712 reader, smd->verts[i].binds[j].verts_num, &smd->verts[i].binds[j].vert_weights);
1717 return MEM_new<BindVertsImplicitSharing>(
1725 N_(
"SurfaceDeform"),
1726 "SurfaceDeformModifierData",
1728 &RNA_SurfaceDeformModifier,
1731 ICON_MOD_MESHDEFORM,
int BKE_mesh_wrapper_vert_len(const Mesh *mesh)
void BKE_mesh_wrapper_ensure_mdata(Mesh *mesh)
void BKE_mesh_wrapper_vert_coords_copy_with_mat4(const Mesh *mesh, float(*vert_coords)[3], int vert_coords_len, const float mat[4][4])
int BKE_mesh_wrapper_face_len(const Mesh *mesh)
void(*)(void *user_data, Object *ob, ID **idpoin, LibraryForeachIDCallbackFlag cb_flag) IDWalkFunc
Mesh * BKE_modifier_get_evaluated_mesh_from_evaluated_object(Object *ob_eval)
void BKE_modifier_copydata_generic(const ModifierData *md, ModifierData *md_dst, int flag)
@ eModifierTypeFlag_SupportsEditmode
@ eModifierTypeFlag_AcceptsMesh
ModifierData * BKE_modifier_get_original(const Object *object, ModifierData *md)
void BKE_modifier_set_error(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
void void BKE_modifier_set_warning(const Object *ob, ModifierData *md, const char *format,...) ATTR_PRINTF_FORMAT(3
int BLI_bvhtree_find_nearest(const BVHTree *tree, const float co[3], BVHTreeNearest *nearest, BVHTree_NearestPointCallback callback, void *userdata)
MINLINE float max_ff(float a, float b)
MINLINE float min_ff(float a, float b)
MINLINE float interpf(float target, float origin, float t)
MINLINE float signf(float f)
float dist_squared_to_line_segment_v3(const float p[3], const float l1[3], const float l2[3])
MINLINE float area_tri_v2(const float v1[2], const float v2[2], const float v3[2])
bool isect_point_poly_v2(const float pt[2], const float verts[][2], unsigned int nr)
void interp_weights_tri_v3(float w[3], const float v1[3], const float v2[3], const float v3[3], const float co[3])
void map_to_plane_axis_angle_v2_v3v3fl(float r_co[2], const float co[3], const float axis[3], float angle)
void interp_weights_poly_v2(float w[], float v[][2], int n, const float co[2])
bool isect_line_plane_v3(float r_isect_co[3], const float l1[3], const float l2[3], const float plane_co[3], const float plane_no[3]) ATTR_WARN_UNUSED_RESULT
float normal_poly_v3(float n[3], const float verts[][3], unsigned int nr)
bool is_poly_convex_v2(const float verts[][2], unsigned int nr)
float normal_tri_v3(float n[3], const float v1[3], const float v2[3], const float v3[3])
float dist_to_line_v2(const float p[2], const float l1[2], const float l2[2])
void mul_m4_m4m4(float R[4][4], const float A[4][4], const float B[4][4])
void mul_v3_m4v3(float r[3], const float mat[4][4], const float vec[3])
bool invert_m4_m4(float inverse[4][4], const float mat[4][4])
MINLINE float len_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
MINLINE float len_squared_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
float angle_normalized_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void madd_v2_v2fl(float r[2], const float a[2], float f)
void mid_v3_v3_array(float r[3], const float(*vec_arr)[3], unsigned int vec_arr_num)
MINLINE void sub_v2_v2(float r[2], const float a[2])
MINLINE void sub_v3_v3(float r[3], const float a[3])
MINLINE float len_squared_v3v3(const float a[3], const float b[3]) ATTR_WARN_UNUSED_RESULT
MINLINE void sub_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE float len_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
MINLINE void copy_v2_v2(float r[2], const float a[2])
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 add_v3_v3v3(float r[3], const float a[3], const float b[3])
MINLINE void cross_v3_v3v3(float r[3], const float a[3], const float b[3])
float angle_signed_v2v2(const float v1[2], const float v2[2]) ATTR_WARN_UNUSED_RESULT
void mid_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void sub_v2_v2v2(float r[2], const float a[2], const float b[2])
MINLINE void zero_v2(float r[2])
MINLINE float dot_v2v2(const float a[2], const float b[2]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v2(float n[2])
MINLINE void zero_v3(float r[3])
float angle_normalized_v3v3(const float v1[3], const float v2[3]) ATTR_WARN_UNUSED_RESULT
MINLINE float normalize_v3(float n[3])
void mid_v3_v3v3v3(float v[3], const float v1[3], const float v2[3], const float v3[3])
MINLINE float len_v3(const float a[3]) ATTR_WARN_UNUSED_RESULT
ATTR_WARN_UNUSED_RESULT const size_t num
void BLI_task_parallel_range(int start, int stop, void *userdata, TaskParallelRangeFunc func, const TaskParallelSettings *settings)
BLI_INLINE void BLI_parallel_range_settings_defaults(TaskParallelSettings *settings)
#define MEMCMP_STRUCT_AFTER_IS_ZERO(struct_var, member)
#define MEMCPY_STRUCT_AFTER(struct_dst, struct_src, member)
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)
bool DEG_is_active(const Depsgraph *depsgraph)
void DEG_add_object_relation(DepsNodeHandle *node_handle, Object *object, eDepsObjectComponentType component, const char *description)
#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_SurfaceDeform
@ MOD_SDEF_MODE_CORNER_TRIS
Object is a sort of wrapper for general info.
static double angle(const Eigen::Vector3d &v1, const Eigen::Vector3d &v2)
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 foreach_ID_link(ModifierData *md, Object *ob, IDWalkFunc walk, void *user_data)
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)
BMesh const char void * data
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
BindVertsImplicitSharing(SDefVert *data, int bind_verts_num)
constexpr int64_t size() const
constexpr int64_t start() const
constexpr int64_t size() const
constexpr T * data() const
constexpr Span slice(int64_t start, int64_t size) const
constexpr IndexRange index_range() const
IndexRange index_range() const
static void update_depsgraph(tGraphSliderOp *gso)
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)
void copy_shared_pointer(T *src_ptr, const ImplicitSharingInfo *src_sharing_info, T **r_dst_ptr, const ImplicitSharingInfo **r_dst_sharing_info)
void free_shared_data(T **data, const ImplicitSharingInfo **sharing_info)
VecBase< int32_t, 2 > int2
PointerRNA RNA_pointer_get(PointerRNA *ptr, const char *name)
int RNA_string_length(PointerRNA *ptr, const char *name)
bool RNA_pointer_is_null(const PointerRNA *ptr)
bool RNA_boolean_get(PointerRNA *ptr, const char *name)
const float(* vertexCos)[3]
blender::Span< int > tri_faces
const SDefEdgePolys * edge_polys
blender::Span< blender::int2 > edges
blender::OffsetIndices< int > polys
blender::Span< blender::int3 > corner_tris
blender::bke::BVHTreeFromMesh * treeData
const SDefAdjacencyArray * vert_edges
blender::Span< int > corner_edges
blender::Span< int > corner_verts
const MDeformVert * dvert
float corner_edgemid_angles[2]
float dominant_angle_weight
float cent_edgemid_vecs_v2[2][2]
float point_edgemid_angles[2]
SDefBindPoly * bind_polys
uiLayout & column(bool align)
void separator(float factor=1.0f, LayoutSeparatorType type=LayoutSeparatorType::Auto)
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)