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++;
313 for (
const int i : edges.index_range()) {
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) {
344 *indices = corner_verts[i];
350 for (
int i = 0; corner_edges[i] != edge; i++) {
351 *indices = corner_verts[i];
357 const int *
const corner_verts,
358 const uint loopstart,
361 for (
int i = loopstart; i < num; i++) {
362 *indices = corner_verts[i];
366 for (
int i = 0; i < loopstart; i++) {
367 *indices = corner_verts[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) {
436 if (
len_squared_v2v2(prev_prev_co, coords[i]) < FLT_EPSILON * FLT_EPSILON) {
441 if (1.0f -
dot_v2v2(prev_vec, curr_vec) < FLT_EPSILON) {
458 for (
int i = 0; i < bwdata->
faces_num; bpoly++, i++) {
475 const float point_co[3])
478 const SDefAdjacency *
const vert_edges = data->vert_edges[nearest].first;
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) {
497 bwdata->
faces_num = data->vert_edges[nearest].num / 2;
501 if (bpoly ==
nullptr) {
511 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
514 for (
int i = 0; i < edge_polys[edge_ind].
num; i++) {
518 for (
int j = 0; j < bwdata->
faces_num; bpoly++, j++) {
543 bpoly->
coords =
static_cast<float(*)[3]
>(
545 if (bpoly->
coords ==
nullptr) {
551 bpoly->
coords_v2 =
static_cast<float(*)[2]
>(
559 for (
int j = 0; j < face.size(); j++) {
560 const int vert_i = data->corner_verts[face.start() + j];
561 const int edge_i = data->corner_edges[face.start() + j];
565 if (vert_i == nearest) {
567 bpoly->
edge_vert_inds[0] = (j == 0) ? (face.size() - 1) : (j - 1);
568 bpoly->
edge_vert_inds[1] = (j == face.size() - 1) ? (0) : (j + 1);
589 for (
int j = 0; j < face.size(); j++) {
598 data->success = is_poly_valid;
636 float corner_angles[2];
649 if (bpoly->
scales[0] < FLT_EPSILON || bpoly->
scales[1] < FLT_EPSILON ||
668 float cent_point_vec[2], point_angles[2];
674 signf(corner_angles[0]);
676 signf(corner_angles[1]);
678 if (point_angles[0] <= 0 && point_angles[1] <= 0) {
681 if (point_angles[0] < point_angles[1]) {
725 if (!inf_weight_flags) {
726 for (vedge = vert_edges; vedge; vedge = vedge->
next) {
729 float ang_weights[2];
731 uint edge_on_poly[2];
733 epolys = &edge_polys[edge_ind];
738 for (
int i = 0, j = 0; (i < bwdata->
faces_num) && (j < epolys->num); bpoly++, i++) {
754 if (epolys->
num == 1) {
756 bpolys[0]->edgemid_angle);
759 else if (epolys->
num == 2) {
761 bpolys[0]->edgemid_angle);
763 bpolys[1]->edgemid_angle);
775 if (!inf_weight_flags) {
778 for (
int i = 0; i < bwdata->
faces_num; bpoly++, i++) {
779 float corner_angle_weights[2];
780 float scale_weight,
sqr, inv_sqr;
785 if (isnan(corner_angle_weights[0]) || isnan(corner_angle_weights[1])) {
792 if (corner_angle_weights[0] < corner_angle_weights[1]) {
817 scale_weight /= scale_weight + (edge_angle_b /
max_ff(edge_angle_b, bpoly->
edgemid_angle));
820 sqr = scale_weight * scale_weight;
821 inv_sqr = 1.0f - scale_weight;
823 scale_weight =
sqr / (
sqr + inv_sqr);
825 BLI_assert(scale_weight >= 0 && scale_weight <= 1);
858 for (
int i = 0; i < bwdata->
faces_num; bpoly++, i++) {
873 for (
int i = 0; i < bwdata->
faces_num; bpoly++, i++) {
895 tot_weight += bpoly->
weight;
900 for (
int i = 0; i < bwdata->
faces_num; bpoly++, i++) {
901 bpoly->
weight /= tot_weight;
907 if (bpoly->
weight >= FLT_EPSILON) {
928 const float point_co_proj[3],
929 const float normal[3])
935 normal_dist =
len_v3(disp_vec);
937 if (
dot_v3v3(disp_vec, normal) < 0) {
950 float point_co_proj[3];
953 SDefVert *sdvert = data->bind_verts + index;
960 sdvert->
binds =
nullptr;
965 if (data->sparse_bind) {
968 if (data->dvert && data->defgrp_index != -1) {
972 if (data->invert_vgroup) {
973 weight = 1.0f - weight;
977 sdvert->
binds =
nullptr;
986 if (bwdata ==
nullptr) {
987 sdvert->
binds =
nullptr;
994 if (sdvert->
binds ==
nullptr) {
1002 sdbind = sdvert->
binds;
1006 for (
int i = 0; i < bwdata->
binds_num; bpoly++) {
1007 if (bpoly->
weight >= FLT_EPSILON) {
1033 for (
int j = 0; j < bpoly->
verts_num; j++) {
1034 const int vert_i = data->corner_verts[bpoly->
loopstart + j];
1046 float cent[3],
norm[3];
1047 float v1[3],
v2[3], v3[3];
1168 float (*vertexCos)[3],
1170 uint target_faces_num,
1171 uint target_verts_num,
1181 uint tedges_num = target->edges_num;
1186 if (vert_edges ==
nullptr) {
1193 if (adj_array ==
nullptr) {
1201 if (edge_polys ==
nullptr) {
1210 if (smd_orig->
verts ==
nullptr) {
1217 if (treeData.
tree ==
nullptr) {
1221 smd_orig->
verts =
nullptr;
1225 adj_result =
buildAdjacencyMap(polys, edges, corner_edges, vert_edges, adj_array, edge_polys);
1229 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1233 smd_orig->
verts =
nullptr;
1249 data.vert_edges = vert_edges;
1250 data.edge_polys = edge_polys;
1253 data.corner_verts = corner_verts;
1254 data.corner_edges = corner_edges;
1255 data.corner_tris = target->corner_tris();
1256 data.tri_faces = target->corner_tri_faces();
1257 data.targetCos =
static_cast<float(*)[3]
>(
1258 MEM_malloc_arrayN(target_verts_num,
sizeof(
float[3]),
"SDefTargetBindVertArray"));
1259 data.bind_verts = smd_orig->
verts;
1260 data.vertexCos = vertexCos;
1261 data.falloff = smd_orig->
falloff;
1264 data.defgrp_index = defgrp_index;
1265 data.invert_vgroup = invert_vgroup;
1266 data.sparse_bind = sparse_bind;
1268 if (data.targetCos ==
nullptr) {
1276 for (
int i = 0; i < target_verts_num; i++) {
1282 settings.use_threading = (verts_num > 10000);
1300 ob, (
ModifierData *)smd_eval,
"Target has edges with more than two polygons");
1328 return data.success == 1;
1336 const SDefBind *sdbind = data->bind_verts[index].binds;
1337 const int sdbind_num = data->bind_verts[index].binds_num;
1338 const uint vertex_idx = data->bind_verts[index].vertex_idx;
1339 float *
const vertexCos = data->vertexCos[vertex_idx];
1340 float norm[3], temp[3], offset[3];
1343 float weight = 1.0f;
1345 if (data->dvert && data->defgrp_index != -1) {
1348 if (data->invert_vgroup) {
1349 weight = 1.0f - weight;
1355 if (weight == 0.0f) {
1362 for (
int j = 0; j < sdbind_num; j++) {
1363 max_verts = std::max(max_verts,
int(sdbind[j].verts_num));
1369 for (
int j = 0; j < sdbind_num; j++, sdbind++) {
1370 for (
int k = 0; k < sdbind->
verts_num; k++) {
1375 norm,
reinterpret_cast<const float(*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1378 switch (sdbind->
mode) {
1389 for (
int k = 0; k < sdbind->
verts_num; k++) {
1399 cent,
reinterpret_cast<const float(*)[3]
>(coords_buffer.
data()), sdbind->
verts_num);
1417 madd_v3_v3fl(vertexCos, offset, data->strength * weight);
1422 float (*vertexCos)[3],
1429 uint target_verts_num, target_faces_num;
1433 if (smd->
verts !=
nullptr) {
1455 if (smd->
verts ==
nullptr) {
1463 float tmp_mat[4][4];
1466 mul_m4_m4m4(smd_orig->
mat, tmp_mat, ob_target->object_to_world().ptr());
1481 smd->
flags &= ~MOD_SDEF_BIND;
1490 ob, md,
"Vertices changed from %u to %u", smd->
mesh_verts_num, verts_num);
1500 ob, md,
"Target polygons changed from %u to %u", smd->
target_polys_num, target_faces_num);
1508 "Target vertices changed from %u to %u",
1520 "Target vertices changed from %u to %u, continuing anyway",
1543 data.targetCos =
static_cast<float(*)[3]
>(
1545 data.vertexCos = vertexCos;
1547 data.defgrp_index = defgrp_index;
1548 data.invert_vgroup = invert_vgroup;
1551 if (data.targetCos !=
nullptr) {
1553 target, data.targetCos, target_verts_num, smd->
mat);
1571 reinterpret_cast<float(*)[3]
>(positions.data()),
1648 smd.
verts =
nullptr;
1654 if (smd.
verts !=
nullptr) {
1661 if (bind_verts[i].binds) {
1662 for (
int j = 0; j < bind_verts[i].
binds_num; j++) {
1664 writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_inds);
1672 writer, bind_verts[i].binds[j].verts_num, bind_verts[i].binds[j].vert_weights);
1711 N_(
"SurfaceDeform"),
1712 "SurfaceDeformModifierData",
1714 &RNA_SurfaceDeformModifier,
1717 ICON_MOD_MESHDEFORM,
void free_bvhtree_from_mesh(BVHTreeFromMesh *data)
BVHTree * BKE_bvhtree_from_mesh_get(BVHTreeFromMesh *data, const Mesh *mesh, BVHCacheType bvh_cache_type, int tree_type)
@ BVHTREE_FROM_CORNER_TRIS
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)
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(*)(void *user_data, Object *ob, ID **idpoin, int cb_flag) IDWalkFunc
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
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_read_float3_array(BlendDataReader *reader, int array_size, float **ptr_p)
void BLO_write_uint32_array(BlendWriter *writer, uint num, const uint32_t *data_ptr)
void BLO_write_float3_array(BlendWriter *writer, uint num, const float *data_ptr)
void BLO_read_float_array(BlendDataReader *reader, int array_size, float **ptr_p)
void BLO_read_uint32_array(BlendDataReader *reader, int array_size, uint32_t **ptr_p)
void BLO_write_float_array(BlendWriter *writer, uint num, const float *data_ptr)
#define BLO_write_struct_array(writer, struct_name, array_size, 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 ID_IS_LINKED(_id)
#define ID_IS_OVERRIDE_LIBRARY(_id)
#define CD_MASK_MDEFORMVERT
#define DNA_struct_default_get(struct_name)
@ eModifierFlag_OverrideLibrary_Local
struct SurfaceDeformModifierData SurfaceDeformModifierData
@ 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.
void modifier_panel_end(uiLayout *layout, PointerRNA *ptr)
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_vgroup_ui(uiLayout *layout, PointerRNA *ptr, PointerRNA *ob_ptr, const char *vgroup_prop, const char *invert_vgroup_prop, const char *text)
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)
void uiItemS(uiLayout *layout)
void uiItemO(uiLayout *layout, const char *name, int icon, const char *opname)
uiLayout * uiLayoutColumn(uiLayout *layout, bool align)
void uiItemR(uiLayout *layout, PointerRNA *ptr, const char *propname, eUI_Item_Flag flag, const char *name, int icon)
ATTR_WARN_UNUSED_RESULT const BMVert * v2
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
constexpr Span slice(int64_t start, int64_t size) const
IndexRange index_range() const
draw_view in_light_buf[] float
void *(* MEM_reallocN_id)(void *vmemh, size_t len, const char *str)
void *(* MEM_malloc_arrayN)(size_t len, size_t size, const char *str)
void *(* MEM_calloc_arrayN)(size_t len, size_t size, const char *str)
void MEM_freeN(void *vmemh)
void *(* MEM_callocN)(size_t len, const char *str)
void *(* MEM_dupallocN)(const void *vmemh)
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
const SDefAdjacencyArray * vert_edges
BVHTreeFromMesh * treeData
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
ccl_device_inline float sqr(float a)