39 const float factor =
math::rcp(
float(indices.size()));
42 result += positions[i] * factor;
56 for (
const int i : vert_neighbors.index_range()) {
57 const Span<int> neighbors = vert_neighbors[i];
59 dst[i] = src[
verts[i]];
83 for (
const int i : vert_neighbors.index_range()) {
106 result += positions[coord.to_index(key)] * factor;
124 const int node_verts_start = i * key.
grid_area;
125 const int grid = grids[i];
133 const int node_vert_index = node_verts_start + offset;
134 const int vert = grid_range[offset];
145 faces, corner_verts, boundary_verts, subdiv_ccg, coord))
155 faces, corner_verts, boundary_verts, subdiv_ccg, coord);
161 new_positions[node_vert_index] = positions[vert];
182 const int grid = grids[i];
183 const int node_verts_start = i * key.
grid_area;
190 const int node_vert_index = node_verts_start + offset;
202 const int index = neighbor.grid_index * key.
grid_area +
221 for (
const BMVert *neighbor : neighbors) {
224 dst[i] =
sum / neighbors.
size();
249 result +=
float3(vert->co) * factor;
278 new_positions[i] =
float3(vert->co);
289 float avg_co[3] = {0.0f, 0.0f, 0.0f};
300 BMVert *v_other = (
e->v1 ==
v) ?
e->v2 :
e->v1;
308 float fac =
dot_v3v3(vec, direction);
309 fac = fac * fac - 0.5f;
334 const GSpan color_attribute,
341 for (
const int i : vert_neighbors.index_range()) {
343 const Span<int> neighbors = vert_neighbors[i];
344 for (
const int vert : neighbors) {
346 faces, corner_verts, vert_to_face_map, color_attribute, color_domain, vert);
348 smooth_colors[i] =
sum / neighbors.
size();
368 const float3 weighted_o = orig_positions[i] * alpha;
369 const float3 weighted_q = positions[i] * (1.0f - alpha);
370 const float3 d = weighted_o + weighted_q;
385 float3 b_current_vert = average_laplacian_disp[i] * (1.0f -
beta);
386 b_current_vert += laplacian_disp[i] *
beta;
387 translations[i] = -b_current_vert;
393 const float3 &smoothed_position)
398 float3 smooth_closest_plane;
401 return smooth_closest_plane - current_position;
409 for (
const int vert : neighbors) {
410 const float3 to_neighbor = vert_positions[vert] - current_position;
418 const float3 ¤t_position,
423 const float3 to_neighbor = positions[coord.to_index(key)] - current_position;
433 for (
BMVert *vert : neighbors) {
434 const float3 neighbor_pos = vert->co;
435 const float3 to_neighbor = neighbor_pos - current_position;
449 const bool filter_boundary_face_sets,
458 neighbors.resize(
verts.size());
460 faces, corner_verts, vert_to_face_map, boundary_verts, hide_poly,
verts, neighbors);
462 for (
const int i :
verts.index_range()) {
463 if (factors[i] == 0.0f) {
464 translations[i] =
float3(0);
469 if (neighbors[i].
size() <= 2) {
470 translations[i] =
float3(0);
474 const bool is_boundary = boundary_verts[
verts[i]];
476 neighbors[i].remove_if([&](
const int vert) {
return !boundary_verts[vert]; });
479 if (filter_boundary_face_sets) {
480 neighbors[i].remove_if([&](
const int vert) {
485 if (neighbors[i].is_empty()) {
486 translations[i] =
float3(0);
494 if (is_boundary && neighbors[i].
size() == 2) {
497 translations[i] =
float3(0);
502 normal = vert_normals[
verts[i]];
506 vert_positions[
verts[i]], normal, smoothed_position);
508 translations[i] = translation * factors[i];
519 const bool filter_boundary_face_sets,
532 neighbors.resize(grid_verts_num);
537 const int node_start = i * key.
grid_area;
541 const int node_vert = node_start + offset;
542 const int vert = grid_range[offset];
543 if (factors[node_vert] == 0.0f) {
544 translations[node_vert] =
float3(0);
549 if (neighbors[node_vert].
size() <= 2) {
550 translations[node_vert] =
float3(0);
560 faces, corner_verts, boundary_verts, subdiv_ccg, coord);
563 neighbors[node_vert].remove_if([&](
const SubdivCCGCoord neighbor) {
565 faces, corner_verts, boundary_verts, subdiv_ccg, neighbor);
569 if (filter_boundary_face_sets) {
570 neighbors[node_vert].remove_if([&](
const SubdivCCGCoord neighbor) {
572 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, neighbor);
576 if (neighbors[i].is_empty()) {
577 translations[node_vert] =
float3(0);
585 if (is_boundary && neighbors[i].
size() == 2) {
587 key, positions, positions[vert], neighbors[node_vert]);
589 translations[node_vert] =
float3(0);
594 normal = normals[vert];
598 positions[vert], normal, smoothed_position);
600 translations[node_vert] = translation * factors[node_vert];
608 const int face_set_offset,
609 const bool filter_boundary_face_sets,
617 neighbors.resize(
verts.size());
622 if (factors[i] == 0.0f) {
623 translations[i] =
float3(0);
629 if (neighbors[i].
size() <= 2) {
630 translations[i] =
float3(0);
640 if (filter_boundary_face_sets) {
641 neighbors[i].remove_if([&](
const BMVert *vert) {
646 if (neighbors[i].is_empty()) {
647 translations[i] =
float3(0);
656 if (is_boundary && neighbors[i].
size() == 2) {
659 translations[i] =
float3(0);
670 translations[i] = translation * factors[i];
676 const int iterations,
690 switch (pbvh.
type()) {
694 const Mesh &mesh = *
static_cast<const Mesh *
>(
object.data);
696 const Span<int> corner_verts = mesh.corner_verts();
703 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
708 tls.vert_neighbors.resize(
verts.size());
712 tls.new_factors.resize(
verts.size());
726 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
729 const Span<int> grids = nodes[node_index].grids();
732 tls.new_factors.resize(grid_verts_num);
741 const int node_start = i * key.
grid_area;
743 key, grid_hidden, grids[i], [&](
const int offset) {
744 data[i] = new_factors[node_start + offset];
754 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
760 tls.new_factors.resize(
verts.size());
int CCG_grid_xy_to_index(const int grid_size, const int x, const int y)
A BVH for high poly meshes.
const blender::Set< BMVert *, 0 > & BKE_pbvh_bmesh_node_unique_verts(blender::bke::pbvh::BMeshNode *node)
bool BKE_subdiv_ccg_coord_is_mesh_boundary(blender::OffsetIndices< int > faces, blender::Span< int > corner_verts, blender::BitSpan boundary_verts, const SubdivCCG &subdiv_ccg, SubdivCCGCoord coord)
CCGKey BKE_subdiv_ccg_key_top_level(const SubdivCCG &subdiv_ccg)
void BKE_subdiv_ccg_foreach_visible_grid_vert(const CCGKey &key, const blender::BitGroupVector<> &grid_hidden, const int grid, const Fn &fn)
void BKE_subdiv_ccg_neighbor_coords_get(const SubdivCCG &subdiv_ccg, const SubdivCCGCoord &coord, bool include_duplicates, SubdivCCGNeighbors &r_neighbors)
void plane_from_point_normal_v3(float r_plane[4], const float plane_co[3], const float plane_no[3])
void closest_to_plane_v3(float r_close[3], const float plane[4], const float pt[3])
MINLINE void madd_v3_v3fl(float r[3], const float a[3], float f)
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 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])
Read Guarded memory(de)allocation.
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
bool BM_vert_is_boundary(const BMVert *v)
BLI_INLINE bool BM_edge_is_boundary(const BMEdge *e) ATTR_WARN_UNUSED_RESULT ATTR_NONNULL()
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
ATTR_WARN_UNUSED_RESULT const BMVert * v
static DBVT_INLINE btScalar size(const btDbvtVolume &a)
static T sum(const btAlignedObjectArray< T > &items)
constexpr int64_t size() const
constexpr Span< T > as_span() const
constexpr int64_t size() const
constexpr IndexRange index_range() const
constexpr bool is_empty() const
int64_t remove_if(Predicate &&predicate)
Span< NodeT > nodes() const
void foreach_index(Fn &&fn) const
IndexRange grid_range(const int grid_area, const int grid)
pbvh::Tree * pbvh_get(Object &object)
IndexMask all_leaf_nodes(const Tree &pbvh, IndexMaskMemory &memory)
float4 color_vert_get(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face_map, GSpan color_attribute, bke::AttrDomain color_domain, int vert)
bool vert_has_unique_face_set(const GroupedSpan< int > vert_to_face_map, const Span< int > face_sets, int vert)
Span< int > node_visible_verts(const bke::pbvh::MeshNode &node, const Span< bool > hide_vert, Vector< int > &indices)
void calc_relaxed_translations_grids(const SubdivCCG &subdiv_ccg, const OffsetIndices< int > faces, const Span< int > corner_verts, const Span< int > face_sets, const GroupedSpan< int > vert_to_face_map, const BitSpan boundary_verts, const Span< int > grids, const bool filter_boundary_face_sets, const Span< float > factors, Vector< Vector< SubdivCCGCoord > > &neighbors, const MutableSpan< float3 > translations)
void average_data_bmesh(const Span< T > src, const Set< BMVert *, 0 > &verts, const MutableSpan< T > dst)
void neighbor_position_average_interior_grids(const OffsetIndices< int > faces, const Span< int > corner_verts, const BitSpan boundary_verts, const SubdivCCG &subdiv_ccg, const Span< int > grids, const MutableSpan< float3 > new_positions)
static float3 translation_to_plane(const float3 ¤t_position, const float3 &normal, const float3 &smoothed_position)
template void neighbor_data_average_mesh< float3 >(Span< float3 >, Span< Vector< int > >, MutableSpan< float3 >)
static float3 calc_boundary_normal_corner(const float3 ¤t_position, const Span< float3 > vert_positions, const Span< int > neighbors)
void neighbor_data_average_mesh_check_loose(const Span< T > src, const Span< int > verts, const Span< Vector< int > > vert_neighbors, const MutableSpan< T > dst)
void neighbor_position_average_interior_bmesh(const Set< BMVert *, 0 > &verts, const MutableSpan< float3 > new_positions)
template void neighbor_data_average_mesh_check_loose< float >(Span< float >, Span< int >, Span< Vector< int > >, MutableSpan< float >)
void calc_relaxed_translations_faces(const Span< float3 > vert_positions, const Span< float3 > vert_normals, const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const BitSpan boundary_verts, const Span< int > face_sets, const Span< bool > hide_poly, const bool filter_boundary_face_sets, const Span< int > verts, const Span< float > factors, Vector< Vector< int > > &neighbors, const MutableSpan< float3 > translations)
static float3 average_positions(const CCGKey &key, const Span< float3 > positions, const Span< SubdivCCGCoord > coords)
void calc_relaxed_translations_bmesh(const Set< BMVert *, 0 > &verts, const Span< float3 > positions, const int face_set_offset, const bool filter_boundary_face_sets, const Span< float > factors, Vector< Vector< BMVert * > > &neighbors, const MutableSpan< float3 > translations)
void surface_smooth_laplacian_step(const Span< float3 > positions, const Span< float3 > orig_positions, const Span< float3 > average_positions, const float alpha, MutableSpan< float3 > laplacian_disp, MutableSpan< float3 > translations)
template void average_data_grids< float3 >(const SubdivCCG &, Span< float3 >, Span< int >, MutableSpan< float3 >)
T calc_average(const Span< T > positions, const Span< int > indices)
void surface_smooth_displace_step(const Span< float3 > laplacian_disp, const Span< float3 > average_laplacian_disp, const float beta, const MutableSpan< float3 > translations)
void neighbor_color_average(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face_map, const GSpan color_attribute, const bke::AttrDomain color_domain, const Span< Vector< int > > vert_neighbors, const MutableSpan< float4 > smooth_colors)
template void neighbor_data_average_mesh< float >(Span< float >, Span< Vector< int > >, MutableSpan< float >)
void bmesh_four_neighbor_average(float avg[3], const float3 &direction, const BMVert *v)
void neighbor_data_average_mesh(const Span< T > src, const Span< Vector< int > > vert_neighbors, const MutableSpan< T > dst)
template void neighbor_data_average_mesh< float4 >(Span< float4 >, Span< Vector< int > >, MutableSpan< float4 >)
void average_data_grids(const SubdivCCG &subdiv_ccg, const Span< T > src, const Span< int > grids, const MutableSpan< T > dst)
template void average_data_grids< float >(const SubdivCCG &, Span< float >, Span< int >, MutableSpan< float >)
void blur_geometry_data_array(const Object &object, const int iterations, const MutableSpan< float > data)
template void average_data_bmesh< float3 >(Span< float3 > src, const Set< BMVert *, 0 > &, MutableSpan< float3 >)
template void average_data_bmesh< float >(Span< float > src, const Set< BMVert *, 0 > &, MutableSpan< float >)
template void neighbor_data_average_mesh_check_loose< float3 >(Span< float3 >, Span< int >, Span< Vector< int > >, MutableSpan< float3 >)
void neighbor_position_average_bmesh(const Set< BMVert *, 0 > &verts, const MutableSpan< float3 > new_positions)
void calc_vert_neighbors_interior(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, BitSpan boundary_verts, Span< bool > hide_poly, Span< int > verts, MutableSpan< Vector< int > > result)
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
void calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, MutableSpan< Vector< int > > result)
Span< BMVert * > vert_neighbors_get_interior_bmesh(BMVert &vert, Vector< BMVert *, 64 > &r_neighbors)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< float, 3 > float3
blender::Vector< SubdivCCGCoord, 256 > coords
blender::Array< blender::float3 > normals
blender::Array< blender::float3 > positions
ccl_device_inline float beta(float x, float y)