34#include "RNA_prototypes.hh"
270 if (smd->
target !=
nullptr) {
296 for (
const int edge_i : corner_edges.
slice(polys[
i])) {
297 if (edge_polys[edge_i].
num == 0) {
298 edge_polys[edge_i].
polys[0] =
i;
299 edge_polys[edge_i].
polys[1] = -1;
300 edge_polys[edge_i].
num++;
302 else if (edge_polys[edge_i].
num == 1) {
303 edge_polys[edge_i].
polys[1] =
i;
304 edge_polys[edge_i].
num++;
317 vert_edges[edge[0]].
first = adj;
318 vert_edges[edge[0]].
num += edge_polys[
i].
num;
323 vert_edges[edge[1]].
first = adj;
324 vert_edges[edge[1]].
num += edge_polys[
i].
num;
332 const int *
const corner_verts,
333 const int *
const corner_edges,
339 for (
int i = 0;
i <
num;
i++) {
340 if (corner_edges[
i] == edge) {
350 for (
int i = 0; corner_edges[
i] != edge;
i++) {
357 const int *
const corner_verts,
358 const uint loopstart,
361 for (
int i = loopstart;
i <
num;
i++) {
366 for (
int i = 0;
i < loopstart;
i++) {
386 data->treeData->tree, t_point, &nearest,
data->treeData->nearest_callback,
data->treeData);
390 for (
int i = 0;
i < face.
size();
i++) {
391 const int edge_i =
data->corner_edges[face.
start() +
i];
394 point_co,
data->targetCos[edge[0]],
data->targetCos[edge[1]]);
396 if (dist < max_dist) {
414 float prev_co[2], prev_prev_co[2];
415 float curr_vec[2], prev_vec[2];
426 for (
int i = 0;
i < nr;
i++) {
431 if (curr_len < FLT_EPSILON) {
441 if (1.0f -
dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
475 const float point_co[3])
486 const float world[3] = {0.0f, 0.0f, 1.0f};
487 float avg_point_dist = 0.0f;
488 float tot_weight = 0.0f;
489 int inf_weight_flags = 0;
492 if (bwdata ==
nullptr) {
500 if (bpoly ==
nullptr) {
510 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
513 for (
int i = 0;
i < edge_polys[edge_ind].
num;
i++) {
517 for (
int j = 0; j < bwdata->
faces_num; bpoly++, j++) {
543 if (bpoly->
coords ==
nullptr) {
550 "SDefBindPolyCoords_v2");
557 for (
int j = 0; j < face.
size(); j++) {
558 const int vert_i =
data->corner_verts[face.
start() + j];
559 const int edge_i =
data->corner_edges[face.
start() + j];
563 if (vert_i == nearest) {
587 for (
int j = 0; j < face.
size(); j++) {
596 data->success = is_poly_valid;
634 float corner_angles[2];
647 if (bpoly->
scales[0] < FLT_EPSILON || bpoly->
scales[1] < FLT_EPSILON ||
666 float cent_point_vec[2], point_angles[2];
672 signf(corner_angles[0]);
674 signf(corner_angles[1]);
676 if (point_angles[0] <= 0 && point_angles[1] <= 0) {
679 if (point_angles[0] < point_angles[1]) {
723 if (!inf_weight_flags) {
724 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
727 float ang_weights[2];
729 uint edge_on_poly[2];
731 epolys = &edge_polys[edge_ind];
736 for (
int i = 0, j = 0; (
i < bwdata->
faces_num) && (j < epolys->
num); bpoly++,
i++) {
752 if (epolys->
num == 1) {
754 bpolys[0]->edgemid_angle);
757 else if (epolys->
num == 2) {
759 bpolys[0]->edgemid_angle);
761 bpolys[1]->edgemid_angle);
773 if (!inf_weight_flags) {
777 float corner_angle_weights[2];
778 float scale_weight,
sqr, inv_sqr;
783 if (
isnan(corner_angle_weights[0]) ||
isnan(corner_angle_weights[1])) {
790 if (corner_angle_weights[0] < corner_angle_weights[1]) {
815 scale_weight /= scale_weight + (edge_angle_b /
max_ff(edge_angle_b, bpoly->
edgemid_angle));
818 sqr = scale_weight * scale_weight;
819 inv_sqr = 1.0f - scale_weight;
821 scale_weight =
sqr / (
sqr + inv_sqr);
823 BLI_assert(scale_weight >= 0 && scale_weight <= 1);
893 tot_weight += bpoly->
weight;
899 bpoly->
weight /= tot_weight;
905 if (bpoly->
weight >= FLT_EPSILON) {
926 const float point_co_proj[3],
927 const float normal[3])
933 normal_dist =
len_v3(disp_vec);
935 if (
dot_v3v3(disp_vec, normal) < 0) {
948 float point_co_proj[3];
958 sdvert->
binds =
nullptr;
963 if (
data->sparse_bind) {
966 if (
data->dvert &&
data->defgrp_index != -1) {
970 if (
data->invert_vgroup) {
971 weight = 1.0f - weight;
975 sdvert->
binds =
nullptr;
984 if (bwdata ==
nullptr) {
985 sdvert->
binds =
nullptr;
991 if (sdvert->
binds ==
nullptr) {
999 sdbind = sdvert->
binds;
1004 if (bpoly->
weight >= FLT_EPSILON) {
1011 "SDefNgonVertWeights");
1029 for (
int j = 0; j < bpoly->
verts_num; j++) {
1030 const int vert_i =
data->corner_verts[bpoly->
loopstart + j];
1042 float cent[3],
norm[3];
1043 float v1[3],
v2[3], v3[3];
1057 "SDefCentVertInds");
1161 float (*vertexCos)[3],
1163 uint target_faces_num,
1164 uint target_verts_num,
1178 if (vert_edges ==
nullptr) {
1185 if (adj_array ==
nullptr) {
1192 if (edge_polys ==
nullptr) {
1200 if (smd_orig->
verts ==
nullptr) {
1207 if (treeData.
tree ==
nullptr) {
1211 smd_orig->
verts =
nullptr;
1215 adj_result =
buildAdjacencyMap(polys, edges, corner_edges, vert_edges, adj_array, edge_polys);
1219 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1222 smd_orig->
verts =
nullptr;
1237 data.treeData = &treeData;
1238 data.vert_edges = vert_edges;
1239 data.edge_polys = edge_polys;
1242 data.corner_verts = corner_verts;
1243 data.corner_edges = corner_edges;
1244 data.corner_tris = target->corner_tris();
1245 data.tri_faces = target->corner_tri_faces();
1247 "SDefTargetBindVertArray");
1249 data.vertexCos = vertexCos;
1253 data.defgrp_index = defgrp_index;
1254 data.invert_vgroup = invert_vgroup;
1255 data.sparse_bind = sparse_bind;
1257 if (
data.targetCos ==
nullptr) {
1265 for (
int i = 0;
i < target_verts_num;
i++) {
1289 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1316 return data.success == 1;
1324 const SDefBind *sdbind =
data->bind_verts[index].binds;
1325 const int sdbind_num =
data->bind_verts[index].binds_num;
1326 const uint vertex_idx =
data->bind_verts[index].vertex_idx;
1327 float *
const vertexCos =
data->vertexCos[vertex_idx];
1328 float norm[3], temp[3], offset[3];
1331 float weight = 1.0f;
1333 if (
data->dvert &&
data->defgrp_index != -1) {
1336 if (
data->invert_vgroup) {
1337 weight = 1.0f - weight;
1343 if (weight == 0.0f) {
1350 for (
int j = 0; j < sdbind_num; j++) {
1351 max_verts = std::max(max_verts,
int(sdbind[j].verts_num));
1357 for (
int j = 0; j < sdbind_num; j++, sdbind++) {
1358 for (
int k = 0; k < sdbind->
verts_num; k++) {
1363 norm,
reinterpret_cast<const float(*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1366 switch (sdbind->
mode) {
1377 for (
int k = 0; k < sdbind->
verts_num; k++) {
1387 cent,
reinterpret_cast<const float(*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1410 float (*vertexCos)[3],
1417 uint target_verts_num, target_faces_num;
1421 if (smd->
verts !=
nullptr) {
1443 if (smd->
verts ==
nullptr) {
1451 float tmp_mat[4][4];
1454 mul_m4_m4m4(smd_orig->
mat, tmp_mat, ob_target->object_to_world().ptr());
1478 ob, md,
"Vertices changed from %u to %u", smd->
mesh_verts_num, verts_num);
1488 ob, md,
"Target polygons changed from %u to %u", smd->
target_polys_num, target_faces_num);
1496 "Target vertices changed from %u to %u",
1508 "Target vertices changed from %u to %u, continuing anyway",
1532 data.vertexCos = vertexCos;
1534 data.defgrp_index = defgrp_index;
1535 data.invert_vgroup = invert_vgroup;
1538 if (
data.targetCos !=
nullptr) {
1540 target,
data.targetCos, target_verts_num, smd->
mat);
1558 reinterpret_cast<float(*)[3]
>(positions.
data()),
1609 col->op(
"OBJECT_OT_surfacedeform_bind",
IFACE_(
"Unbind"), ICON_NONE);
1613 col->op(
"OBJECT_OT_surfacedeform_bind",
IFACE_(
"Bind"), ICON_NONE);
1635 smd.
verts =
nullptr;
1641 if (smd.
verts !=
nullptr) {
1648 if (bind_verts[
i].binds) {
1649 for (
int j = 0; j < bind_verts[
i].
binds_num; j++) {
1651 writer, bind_verts[
i].binds[j].verts_num, bind_verts[
i].binds[j].vert_inds);
1659 writer, bind_verts[
i].binds[j].verts_num, bind_verts[
i].binds[j].vert_weights);
1698 N_(
"SurfaceDeform"),
1699 "SurfaceDeformModifierData",
1701 &RNA_SurfaceDeformModifier,
1704 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)
void BLO_write_float_array(BlendWriter *writer, int64_t num, const float *data_ptr)
void BLO_read_float3_array(BlendDataReader *reader, int64_t array_size, float **ptr_p)
void BLO_read_uint32_array(BlendDataReader *reader, int64_t array_size, uint32_t **ptr_p)
void BLO_read_float_array(BlendDataReader *reader, int64_t array_size, float **ptr_p)
void BLO_write_float3_array(BlendWriter *writer, int64_t num, const float *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, data_ptr)
void BLO_write_uint32_array(BlendWriter *writer, int64_t num, const uint32_t *data_ptr)
#define BLO_read_struct_array(reader, struct_name, array_size, ptr_p)
bool BLO_write_is_undo(BlendWriter *writer)
#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 DNA_struct_default_get(struct_name)
@ eModifierFlag_OverrideLibrary_Local
@ MOD_SDEF_MODE_CORNER_TRIS
@ eModifierType_SurfaceDeform
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)
void uiLayoutSetActive(uiLayout *layout, bool active)
void uiLayoutSetEnabled(uiLayout *layout, bool enabled)
void uiLayoutSetPropSep(uiLayout *layout, bool is_sep)
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.
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
#define CD_MASK_MDEFORMVERT
#define ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
static void update_depsgraph(tGraphSliderOp *gso)
void * MEM_calloc_arrayN(size_t len, size_t size, const char *str)
void *(* MEM_reallocN_id)(void *vmemh, size_t len, 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 sqr(const float a)
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 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)