Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_point_distribute.cc
| Show First 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | static void sample_mesh_surface(const Mesh &mesh, | ||||
| const VArray<float> *density_factors, | const VArray<float> *density_factors, | ||||
| const int seed, | const int seed, | ||||
| Vector<float3> &r_positions, | Vector<float3> &r_positions, | ||||
| Vector<float3> &r_bary_coords, | Vector<float3> &r_bary_coords, | ||||
| Vector<int> &r_looptri_indices) | Vector<int> &r_looptri_indices) | ||||
| { | { | ||||
| Span<MLoopTri> looptris = get_mesh_looptris(mesh); | Span<MLoopTri> looptris = get_mesh_looptris(mesh); | ||||
| for (const int looptri_index : looptris.index_range()) { | for (const int looptri_index : iter_indices(looptris)) { | ||||
| const MLoopTri &looptri = looptris[looptri_index]; | const MLoopTri &looptri = looptris[looptri_index]; | ||||
| const int v0_loop = looptri.tri[0]; | const int v0_loop = looptri.tri[0]; | ||||
| const int v1_loop = looptri.tri[1]; | const int v1_loop = looptri.tri[1]; | ||||
| const int v2_loop = looptri.tri[2]; | const int v2_loop = looptri.tri[2]; | ||||
| const int v0_index = mesh.mloop[v0_loop].v; | const int v0_index = mesh.mloop[v0_loop].v; | ||||
| const int v1_index = mesh.mloop[v1_loop].v; | const int v1_index = mesh.mloop[v1_loop].v; | ||||
| const int v2_index = mesh.mloop[v2_loop].v; | const int v2_index = mesh.mloop[v2_loop].v; | ||||
| const float3 v0_pos = transform * float3(mesh.mvert[v0_index].co); | const float3 v0_pos = transform * float3(mesh.mvert[v0_index].co); | ||||
| ▲ Show 20 Lines • Show All 54 Lines • ▼ Show 20 Lines | BLI_NOINLINE static void update_elimination_mask_for_close_points( | ||||
| if (minimum_distance <= 0.0f) { | if (minimum_distance <= 0.0f) { | ||||
| return; | return; | ||||
| } | } | ||||
| KDTree_3d *kdtree = build_kdtree(positions_all, initial_points_len); | KDTree_3d *kdtree = build_kdtree(positions_all, initial_points_len); | ||||
| /* The elimination mask is a flattened array for every point, | /* The elimination mask is a flattened array for every point, | ||||
| * so keep track of the index to it separately. */ | * so keep track of the index to it separately. */ | ||||
| for (const int i_instance : positions_all.index_range()) { | for (const int i_instance : iter_indices(positions_all)) { | ||||
| Span<float3> positions = positions_all[i_instance]; | Span<float3> positions = positions_all[i_instance]; | ||||
| const int offset = instance_start_offsets[i_instance]; | const int offset = instance_start_offsets[i_instance]; | ||||
| for (const int i : positions.index_range()) { | for (const int i : iter_indices(positions)) { | ||||
| if (elimination_mask[offset + i]) { | if (elimination_mask[offset + i]) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| struct CallbackData { | struct CallbackData { | ||||
| int index; | int index; | ||||
| MutableSpan<bool> elimination_mask; | MutableSpan<bool> elimination_mask; | ||||
| } callback_data = {offset + i, elimination_mask}; | } callback_data = {offset + i, elimination_mask}; | ||||
| Show All 18 Lines | |||||
| BLI_NOINLINE static void update_elimination_mask_based_on_density_factors( | BLI_NOINLINE static void update_elimination_mask_based_on_density_factors( | ||||
| const Mesh &mesh, | const Mesh &mesh, | ||||
| const VArray<float> &density_factors, | const VArray<float> &density_factors, | ||||
| Span<float3> bary_coords, | Span<float3> bary_coords, | ||||
| Span<int> looptri_indices, | Span<int> looptri_indices, | ||||
| MutableSpan<bool> elimination_mask) | MutableSpan<bool> elimination_mask) | ||||
| { | { | ||||
| Span<MLoopTri> looptris = get_mesh_looptris(mesh); | Span<MLoopTri> looptris = get_mesh_looptris(mesh); | ||||
| for (const int i : bary_coords.index_range()) { | for (const int i : iter_indices(bary_coords)) { | ||||
| if (elimination_mask[i]) { | if (elimination_mask[i]) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| const MLoopTri &looptri = looptris[looptri_indices[i]]; | const MLoopTri &looptri = looptris[looptri_indices[i]]; | ||||
| const float3 bary_coord = bary_coords[i]; | const float3 bary_coord = bary_coords[i]; | ||||
| const int v0_loop = looptri.tri[0]; | const int v0_loop = looptri.tri[0]; | ||||
| Show All 33 Lines | BLI_NOINLINE static void interpolate_attribute_point(const Mesh &mesh, | ||||
| const Span<float3> bary_coords, | const Span<float3> bary_coords, | ||||
| const Span<int> looptri_indices, | const Span<int> looptri_indices, | ||||
| const Span<T> data_in, | const Span<T> data_in, | ||||
| MutableSpan<T> data_out) | MutableSpan<T> data_out) | ||||
| { | { | ||||
| BLI_assert(data_in.size() == mesh.totvert); | BLI_assert(data_in.size() == mesh.totvert); | ||||
| Span<MLoopTri> looptris = get_mesh_looptris(mesh); | Span<MLoopTri> looptris = get_mesh_looptris(mesh); | ||||
| for (const int i : bary_coords.index_range()) { | for (const int i : iter_indices(bary_coords)) { | ||||
| const int looptri_index = looptri_indices[i]; | const int looptri_index = looptri_indices[i]; | ||||
| const MLoopTri &looptri = looptris[looptri_index]; | const MLoopTri &looptri = looptris[looptri_index]; | ||||
| const float3 &bary_coord = bary_coords[i]; | const float3 &bary_coord = bary_coords[i]; | ||||
| const int v0_index = mesh.mloop[looptri.tri[0]].v; | const int v0_index = mesh.mloop[looptri.tri[0]].v; | ||||
| const int v1_index = mesh.mloop[looptri.tri[1]].v; | const int v1_index = mesh.mloop[looptri.tri[1]].v; | ||||
| const int v2_index = mesh.mloop[looptri.tri[2]].v; | const int v2_index = mesh.mloop[looptri.tri[2]].v; | ||||
| Show All 11 Lines | BLI_NOINLINE static void interpolate_attribute_corner(const Mesh &mesh, | ||||
| const Span<float3> bary_coords, | const Span<float3> bary_coords, | ||||
| const Span<int> looptri_indices, | const Span<int> looptri_indices, | ||||
| const Span<T> data_in, | const Span<T> data_in, | ||||
| MutableSpan<T> data_out) | MutableSpan<T> data_out) | ||||
| { | { | ||||
| BLI_assert(data_in.size() == mesh.totloop); | BLI_assert(data_in.size() == mesh.totloop); | ||||
| Span<MLoopTri> looptris = get_mesh_looptris(mesh); | Span<MLoopTri> looptris = get_mesh_looptris(mesh); | ||||
| for (const int i : bary_coords.index_range()) { | for (const int i : iter_indices(bary_coords)) { | ||||
| const int looptri_index = looptri_indices[i]; | const int looptri_index = looptri_indices[i]; | ||||
| const MLoopTri &looptri = looptris[looptri_index]; | const MLoopTri &looptri = looptris[looptri_index]; | ||||
| const float3 &bary_coord = bary_coords[i]; | const float3 &bary_coord = bary_coords[i]; | ||||
| const int loop_index_0 = looptri.tri[0]; | const int loop_index_0 = looptri.tri[0]; | ||||
| const int loop_index_1 = looptri.tri[1]; | const int loop_index_1 = looptri.tri[1]; | ||||
| const int loop_index_2 = looptri.tri[2]; | const int loop_index_2 = looptri.tri[2]; | ||||
| Show All 10 Lines | |||||
| BLI_NOINLINE static void interpolate_attribute_face(const Mesh &mesh, | BLI_NOINLINE static void interpolate_attribute_face(const Mesh &mesh, | ||||
| const Span<int> looptri_indices, | const Span<int> looptri_indices, | ||||
| const Span<T> data_in, | const Span<T> data_in, | ||||
| MutableSpan<T> data_out) | MutableSpan<T> data_out) | ||||
| { | { | ||||
| BLI_assert(data_in.size() == mesh.totpoly); | BLI_assert(data_in.size() == mesh.totpoly); | ||||
| Span<MLoopTri> looptris = get_mesh_looptris(mesh); | Span<MLoopTri> looptris = get_mesh_looptris(mesh); | ||||
| for (const int i : data_out.index_range()) { | for (const int i : iter_indices(data_out)) { | ||||
| const int looptri_index = looptri_indices[i]; | const int looptri_index = looptri_indices[i]; | ||||
| const MLoopTri &looptri = looptris[looptri_index]; | const MLoopTri &looptri = looptris[looptri_index]; | ||||
| const int poly_index = looptri.poly; | const int poly_index = looptri.poly; | ||||
| data_out[i] = data_in[poly_index]; | data_out[i] = data_in[poly_index]; | ||||
| } | } | ||||
| } | } | ||||
| template<typename T> | template<typename T> | ||||
| ▲ Show 20 Lines • Show All 69 Lines • ▼ Show 20 Lines | for (const GeometryInstanceGroup &set_group : set_groups) { | ||||
| continue; | continue; | ||||
| } | } | ||||
| attribute_math::convert_to_static_type(output_data_type, [&](auto dummy) { | attribute_math::convert_to_static_type(output_data_type, [&](auto dummy) { | ||||
| using T = decltype(dummy); | using T = decltype(dummy); | ||||
| GVArray_Span<T> source_span{*source_attribute}; | GVArray_Span<T> source_span{*source_attribute}; | ||||
| for (const int UNUSED(i_set_instance) : set_group.transforms.index_range()) { | for (const int UNUSED(i_set_instance) : iter_indices(set_group.transforms)) { | ||||
| const int offset = instance_start_offsets[i_instance]; | const int offset = instance_start_offsets[i_instance]; | ||||
| Span<float3> bary_coords = bary_coords_array[i_instance]; | Span<float3> bary_coords = bary_coords_array[i_instance]; | ||||
| Span<int> looptri_indices = looptri_indices_array[i_instance]; | Span<int> looptri_indices = looptri_indices_array[i_instance]; | ||||
| MutableSpan<T> instance_span = out_span.typed<T>().slice(offset, bary_coords.size()); | MutableSpan<T> instance_span = out_span.typed<T>().slice(offset, bary_coords.size()); | ||||
| interpolate_attribute<T>( | interpolate_attribute<T>( | ||||
| mesh, bary_coords, looptri_indices, source_domain, source_span, instance_span); | mesh, bary_coords, looptri_indices, source_domain, source_span, instance_span); | ||||
| Show All 38 Lines | for (const float4x4 &transform : set_group.transforms) { | ||||
| MutableSpan<int> ids = result_ids.slice(offset, bary_coords.size()); | MutableSpan<int> ids = result_ids.slice(offset, bary_coords.size()); | ||||
| MutableSpan<float3> normals = result_normals.slice(offset, bary_coords.size()); | MutableSpan<float3> normals = result_normals.slice(offset, bary_coords.size()); | ||||
| MutableSpan<float3> rotations = result_rotations.slice(offset, bary_coords.size()); | MutableSpan<float3> rotations = result_rotations.slice(offset, bary_coords.size()); | ||||
| /* Use one matrix multiplication per point instead of three (for each triangle corner). */ | /* Use one matrix multiplication per point instead of three (for each triangle corner). */ | ||||
| float rotation_matrix[3][3]; | float rotation_matrix[3][3]; | ||||
| mat4_to_rot(rotation_matrix, transform.values); | mat4_to_rot(rotation_matrix, transform.values); | ||||
| for (const int i : bary_coords.index_range()) { | for (const int i : iter_indices(bary_coords)) { | ||||
| const int looptri_index = looptri_indices[i]; | const int looptri_index = looptri_indices[i]; | ||||
| const MLoopTri &looptri = looptris[looptri_index]; | const MLoopTri &looptri = looptris[looptri_index]; | ||||
| const float3 &bary_coord = bary_coords[i]; | const float3 &bary_coord = bary_coords[i]; | ||||
| const int v0_index = mesh.mloop[looptri.tri[0]].v; | const int v0_index = mesh.mloop[looptri.tri[0]].v; | ||||
| const int v1_index = mesh.mloop[looptri.tri[1]].v; | const int v1_index = mesh.mloop[looptri.tri[1]].v; | ||||
| const int v2_index = mesh.mloop[looptri.tri[2]].v; | const int v2_index = mesh.mloop[looptri.tri[2]].v; | ||||
| const float3 v0_pos = float3(mesh.mvert[v0_index].co); | const float3 v0_pos = float3(mesh.mvert[v0_index].co); | ||||
| ▲ Show 20 Lines • Show All 117 Lines • ▼ Show 20 Lines | static void distribute_points_poisson_disk(Span<GeometryInstanceGroup> set_groups, | ||||
| i_instance = 0; | i_instance = 0; | ||||
| for (const GeometryInstanceGroup &set_group : set_groups) { | for (const GeometryInstanceGroup &set_group : set_groups) { | ||||
| const GeometrySet &set = set_group.geometry_set; | const GeometrySet &set = set_group.geometry_set; | ||||
| const MeshComponent &component = *set.get_component_for_read<MeshComponent>(); | const MeshComponent &component = *set.get_component_for_read<MeshComponent>(); | ||||
| const Mesh &mesh = *component.get_for_read(); | const Mesh &mesh = *component.get_for_read(); | ||||
| const GVArray_Typed<float> density_factors = component.attribute_get_for_read<float>( | const GVArray_Typed<float> density_factors = component.attribute_get_for_read<float>( | ||||
| density_attribute_name, ATTR_DOMAIN_CORNER, use_one_default ? 1.0f : 0.0f); | density_attribute_name, ATTR_DOMAIN_CORNER, use_one_default ? 1.0f : 0.0f); | ||||
| for (const int UNUSED(i_set_instance) : set_group.transforms.index_range()) { | for (const int UNUSED(i_set_instance) : iter_indices(set_group.transforms)) { | ||||
| Vector<float3> &positions = positions_all[i_instance]; | Vector<float3> &positions = positions_all[i_instance]; | ||||
| Vector<float3> &bary_coords = bary_coords_all[i_instance]; | Vector<float3> &bary_coords = bary_coords_all[i_instance]; | ||||
| Vector<int> &looptri_indices = looptri_indices_all[i_instance]; | Vector<int> &looptri_indices = looptri_indices_all[i_instance]; | ||||
| const int offset = instance_start_offsets[i_instance]; | const int offset = instance_start_offsets[i_instance]; | ||||
| update_elimination_mask_based_on_density_factors( | update_elimination_mask_based_on_density_factors( | ||||
| mesh, | mesh, | ||||
| density_factors, | density_factors, | ||||
| ▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | case GEO_NODE_POINT_DISTRIBUTE_POISSON: { | ||||
| bary_coords_all, | bary_coords_all, | ||||
| looptri_indices_all); | looptri_indices_all); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| int final_points_len = 0; | int final_points_len = 0; | ||||
| Array<int> instance_start_offsets(set_groups.size()); | Array<int> instance_start_offsets(set_groups.size()); | ||||
| for (const int i : positions_all.index_range()) { | for (const int i : iter_indices(positions_all)) { | ||||
| Vector<float3> &positions = positions_all[i]; | Vector<float3> &positions = positions_all[i]; | ||||
| instance_start_offsets[i] = final_points_len; | instance_start_offsets[i] = final_points_len; | ||||
| final_points_len += positions.size(); | final_points_len += positions.size(); | ||||
| } | } | ||||
| PointCloud *pointcloud = BKE_pointcloud_new_nomain(final_points_len); | PointCloud *pointcloud = BKE_pointcloud_new_nomain(final_points_len); | ||||
| for (const int instance_index : positions_all.index_range()) { | for (const int instance_index : iter_indices(positions_all)) { | ||||
| const int offset = instance_start_offsets[instance_index]; | const int offset = instance_start_offsets[instance_index]; | ||||
| Span<float3> positions = positions_all[instance_index]; | Span<float3> positions = positions_all[instance_index]; | ||||
| memcpy(pointcloud->co + offset, positions.data(), sizeof(float3) * positions.size()); | memcpy(pointcloud->co + offset, positions.data(), sizeof(float3) * positions.size()); | ||||
| } | } | ||||
| uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f); | uninitialized_fill_n(pointcloud->radius, pointcloud->totpoint, 0.05f); | ||||
| GeometrySet geometry_set_out = GeometrySet::create_with_pointcloud(pointcloud); | GeometrySet geometry_set_out = GeometrySet::create_with_pointcloud(pointcloud); | ||||
| Show All 30 Lines | |||||