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) {
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])
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) {
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) {
546 freeBindData(bwdata);
547 data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
551 bpoly->
coords_v2 =
static_cast<float(*)[2]
>(
554 freeBindData(bwdata);
555 data->success = MOD_SDEF_BIND_RESULT_MEM_ERR;
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) {
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];
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,
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;
1248 data.treeData = &treeData;
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"));
1260 data.vertexCos = vertexCos;
1264 data.defgrp_index = defgrp_index;
1265 data.invert_vgroup = invert_vgroup;
1266 data.sparse_bind = sparse_bind;
1268 if (
data.targetCos ==
nullptr) {
1269 BKE_modifier_set_error(ob, (ModifierData *)smd_eval,
"Out of memory");
1270 free_data((ModifierData *)smd_orig);
1276 for (
int i = 0; i < target_verts_num; i++) {
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);
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());
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) {
1552 BKE_mesh_wrapper_vert_coords_copy_with_mat4(
1553 target, data.targetCos, target_verts_num, smd->mat);
1555 TaskParallelSettings settings;
1556 BLI_parallel_range_settings_defaults(&settings);
1557 settings.use_threading = (smd->bind_verts_num > 10000);
1558 BLI_task_parallel_range(0, smd->bind_verts_num, &data, deformVert, &settings);
1560 MEM_freeN(data.targetCos);
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)
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
@ 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_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)
in reality light always falls off quadratically Particle Retrieve the data of the particle that spawned the object for example to give variation to multiple instances of an object Point Retrieve information about points in a point cloud Retrieve the edges of an object as it appears to Cycles topology will always appear triangulated Convert a blackbody temperature to an RGB value Normal Generate a perturbed normal from an RGB normal map image Typically used for faking highly detailed surfaces Generate an OSL shader from a file or text data block Image Sample an image file as a texture Gabor Generate Gabor noise Gradient Generate interpolated color and intensity values based on the input vector Magic Generate a psychedelic color texture Voronoi Generate Worley noise based on the distance to random points Typically used to generate textures such as or biological cells Brick Generate a procedural texture producing bricks Texture Retrieve multiple types of texture coordinates nTypically used as inputs for texture nodes Vector Convert a or normal between world
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 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
draw_view in_light_buf[] float
static void update_depsgraph(tGraphSliderOp *gso)
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)
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
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)