100 result += positions[coord.to_index(key)] * factor;
105template<
bool use_factors>
118 if constexpr (use_factors) {
123 const int node_verts_start =
i * key.
grid_area;
124 const int grid = grids[
i];
132 const int node_vert_index = node_verts_start + offset;
133 const int vert = grid_range[offset];
135 if constexpr (use_factors) {
136 if (factors[node_vert_index] == 0.0f) {
137 new_positions[node_vert_index] = positions[vert];
151 faces, corner_verts, boundary_verts, subdiv_ccg, coord))
161 faces, corner_verts, boundary_verts, subdiv_ccg, coord);
167 new_positions[node_vert_index] = positions[vert];
185 faces, corner_verts, boundary_verts, subdiv_ccg, grids, {}, new_positions);
197 faces, corner_verts, boundary_verts, subdiv_ccg, grids, factors, new_positions);
211 const int grid = grids[
i];
212 const int node_verts_start =
i * key.
grid_area;
219 const int node_vert_index = node_verts_start + offset;
248 for (
const BMVert *neighbor : neighbors) {
295template<
bool use_factors>
301 if constexpr (use_factors) {
308 if constexpr (use_factors) {
309 if (factors[
i] == 0.0f) {
310 new_positions[
i] =
float3(vert->co);
318 new_positions[
i] =
float3(vert->co);
341 float avg_co[3] = {0.0f, 0.0f, 0.0f};
352 BMVert *v_other = (
e->v1 ==
v) ?
e->v2 :
e->v1;
360 float fac =
dot_v3v3(vec, direction);
361 fac = fac * fac - 0.5f;
386 const GSpan color_attribute,
395 const Span<int> neighbors = vert_neighbors[
i];
396 for (
const int vert : neighbors) {
398 faces, corner_verts, vert_to_face_map, color_attribute, color_domain, vert);
420 const float3 weighted_o = orig_positions[
i] * alpha;
421 const float3 weighted_q = positions[
i] * (1.0f - alpha);
422 const float3 d = weighted_o + weighted_q;
437 float3 b_current_vert = average_laplacian_disp[
i] * (1.0f -
beta);
438 b_current_vert += laplacian_disp[
i] *
beta;
439 translations[
i] = -b_current_vert;
445 const float3 &smoothed_position)
450 float3 smooth_closest_plane;
453 return smooth_closest_plane - current_position;
461 for (
const int vert : neighbors) {
462 const float3 to_neighbor = vert_positions[vert] - current_position;
470 const float3 ¤t_position,
475 const float3 to_neighbor = positions[coord.to_index(key)] - current_position;
485 for (
BMVert *vert : neighbors) {
486 const float3 neighbor_pos = vert->co;
487 const float3 to_neighbor = neighbor_pos - current_position;
501 const bool filter_boundary_face_sets,
511 for (
const int i :
verts.index_range()) {
512 if (factors[
i] == 0.0f) {
520 if (neighbors.
size() <= 2) {
525 const bool is_boundary = boundary_verts[
verts[
i]];
527 neighbors.
remove_if([&](
const int vert) {
return !boundary_verts[vert]; });
530 if (filter_boundary_face_sets) {
531 neighbors.
remove_if([&](
const int vert) {
545 if (is_boundary && neighbors.
size() == 2) {
553 normal = vert_normals[
verts[
i]];
557 vert_positions[
verts[
i]], normal, smoothed_position);
559 translations[
i] = translation * factors[
i];
570 const bool filter_boundary_face_sets,
584 const int node_vert = node_start + offset;
585 const int vert = grid_range[offset];
586 if (factors[node_vert] == 0.0f) {
587 translations[node_vert] =
float3(0);
601 if (neighbors.
size() <= 2) {
602 translations[node_vert] =
float3(0);
607 faces, corner_verts, boundary_verts, subdiv_ccg, coord);
612 faces, corner_verts, boundary_verts, subdiv_ccg, neighbor);
616 if (filter_boundary_face_sets) {
619 faces, corner_verts, vert_to_face_map, face_sets, subdiv_ccg, neighbor);
624 translations[node_vert] =
float3(0);
632 if (is_boundary && neighbors.
size() == 2) {
635 translations[node_vert] =
float3(0);
644 positions[vert], normal, smoothed_position);
646 translations[node_vert] = translation * factors[node_vert];
654 const int face_set_offset,
655 const bool filter_boundary_face_sets,
666 if (factors[
i] == 0.0f) {
675 if (neighbors.
size() <= 2) {
686 if (filter_boundary_face_sets) {
702 if (is_boundary && neighbors.
size() == 2) {
716 translations[
i] = translation * factors[
i];
722 const int iterations,
737 switch (pbvh.
type()) {
741 const Mesh &
mesh = *
static_cast<const Mesh *
>(
object.data);
750 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
752 LocalData &tls = all_tls.
local();
760 tls.neighbor_offsets,
763 tls.new_factors.resize(
verts.size());
777 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
779 LocalData &tls = all_tls.
local();
783 tls.new_factors.resize(grid_verts_num);
794 key, grid_hidden, grids[
i], [&](
const int offset) {
795 data[
i] = new_factors[node_start + offset];
805 for ([[maybe_unused]]
const int _ :
IndexRange(iterations)) {
807 LocalData &tls = all_tls.
local();
811 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)
blender::Vector< SubdivCCGCoord, 256 > SubdivCCGNeighborCoords
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])
#define BM_elem_index_get(ele)
#define BM_elem_flag_test(ele, hflag)
#define BM_ITER_ELEM(ele, iter, data, itype)
BMesh const char void * data
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 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)
GAttributeReader lookup(const StringRef attribute_id) const
Span< NodeT > nodes() const
void foreach_index(Fn &&fn) const
static float normals[][3]
ccl_device_inline float beta(const float x, const float y)
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)
static void neighbor_position_average_interior_bmesh_impl(const Set< BMVert *, 0 > &verts, const Span< float > factors, const MutableSpan< float3 > new_positions)
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)
static float3 calc_boundary_normal_corner(const float3 ¤t_position, const Span< float3 > vert_positions, const Span< int > neighbors)
void neighbor_data_average_mesh(const Span< T > src, const GroupedSpan< int > vert_neighbors, const MutableSpan< T > dst)
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 GroupedSpan< int > vert_neighbors, const MutableSpan< float4 > smooth_colors)
template void neighbor_data_average_mesh< float >(Span< float >, GroupedSpan< int >, MutableSpan< float >)
void neighbor_data_average_mesh_check_loose(const Span< T > src, const Span< int > verts, const GroupedSpan< int > vert_neighbors, const MutableSpan< T > dst)
void neighbor_position_average_interior_bmesh(const Set< BMVert *, 0 > &verts, const Span< float > factors, const MutableSpan< float3 > new_positions)
static float3 average_positions(const CCGKey &key, const Span< float3 > positions, const Span< SubdivCCGCoord > coords)
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 neighbor_data_average_mesh_check_loose< float >(Span< float >, Span< int >, GroupedSpan< int >, MutableSpan< float >)
template void average_data_grids< float3 >(const SubdivCCG &, Span< float3 >, Span< int >, MutableSpan< float3 >)
template void neighbor_data_average_mesh< float3 >(Span< float3 >, GroupedSpan< int >, MutableSpan< float3 >)
template void neighbor_data_average_mesh_check_loose< float3 >(Span< float3 >, Span< int >, GroupedSpan< int >, MutableSpan< float3 >)
void surface_smooth_displace_step(const Span< float3 > laplacian_disp, const Span< float3 > average_laplacian_disp, const float beta, const MutableSpan< float3 > translations)
T calc_average(const Span< T > values, const Span< int > indices)
void bmesh_four_neighbor_average(float avg[3], const float3 &direction, const BMVert *v)
static void neighbor_position_average_interior_grids_impl(const OffsetIndices< int > faces, const Span< int > corner_verts, const BitSpan boundary_verts, const SubdivCCG &subdiv_ccg, const Span< int > grids, const Span< float > factors, const MutableSpan< float3 > new_positions)
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 >)
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, const MutableSpan< float3 > translations)
template void average_data_bmesh< float >(Span< float > src, const Set< BMVert *, 0 > &, MutableSpan< float >)
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, const MutableSpan< float3 > translations)
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, const MutableSpan< float3 > translations)
template void neighbor_data_average_mesh< float4 >(Span< float4 >, GroupedSpan< int >, MutableSpan< float4 >)
void neighbor_position_average_bmesh(const Set< BMVert *, 0 > &verts, const MutableSpan< float3 > new_positions)
GroupedSpan< int > calc_vert_neighbors(OffsetIndices< int > faces, Span< int > corner_verts, GroupedSpan< int > vert_to_face, Span< bool > hide_poly, Span< int > verts, Vector< int > &r_offset_data, Vector< int > &r_data)
Vector< BMVert *, 64 > BMeshNeighborVerts
void scatter_data_mesh(Span< T > src, Span< int > indices, MutableSpan< T > dst)
Span< BMVert * > vert_neighbors_get_interior_bmesh(BMVert &vert, BMeshNeighborVerts &r_neighbors)
Span< BMVert * > vert_neighbors_get_bmesh(BMVert &vert, BMeshNeighborVerts &r_neighbors)
Span< int > vert_neighbors_get_mesh(const OffsetIndices< int > faces, const Span< int > corner_verts, const GroupedSpan< int > vert_to_face, const Span< bool > hide_poly, const int vert, Vector< int > &r_neighbors)
void scatter_data_grids(const SubdivCCG &subdiv_ccg, Span< T > node_data, Span< int > grids, MutableSpan< T > dst)
T safe_divide(const T &a, const T &b)
MatBase< T, NumCol, NumRow > normalize(const MatBase< T, NumCol, NumRow > &a)
VecBase< float, 4 > float4
VecBase< float, 3 > float3
int to_index(const CCGKey &key) const
SubdivCCGNeighborCoords coords
blender::Array< blender::float3 > normals
blender::Array< blender::float3 > positions
IndexRange index_range() const