Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc')
-rw-r--r--source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc132
1 files changed, 57 insertions, 75 deletions
diff --git a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
index cfb9cbf7e24..c2cc70296ed 100644
--- a/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
+++ b/source/blender/nodes/geometry/nodes/node_geo_distribute_points_on_faces.cc
@@ -62,15 +62,15 @@ static void node_declare(NodeDeclarationBuilder &b)
b.add_output<decl::Vector>(N_("Rotation")).subtype(PROP_EULER).field_source();
}
-static void node_layout(uiLayout *layout, bContext *UNUSED(C), PointerRNA *ptr)
+static void node_layout(uiLayout *layout, bContext * /*C*/, PointerRNA *ptr)
{
uiItemR(layout, ptr, "distribute_method", 0, "", ICON_NONE);
}
static void node_point_distribute_points_on_faces_update(bNodeTree *ntree, bNode *node)
{
- bNodeSocket *sock_distance_min = (bNodeSocket *)BLI_findlink(&node->inputs, 2);
- bNodeSocket *sock_density_max = (bNodeSocket *)sock_distance_min->next;
+ bNodeSocket *sock_distance_min = static_cast<bNodeSocket *>(BLI_findlink(&node->inputs, 2));
+ bNodeSocket *sock_density_max = static_cast<bNodeSocket *>(sock_distance_min->next);
bNodeSocket *sock_density = sock_density_max->next;
bNodeSocket *sock_density_factor = sock_density->next;
nodeSetSocketAvailability(ntree,
@@ -105,20 +105,21 @@ static void sample_mesh_surface(const Mesh &mesh,
Vector<float3> &r_bary_coords,
Vector<int> &r_looptri_indices)
{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MVert> verts = mesh.verts();
+ const Span<MLoop> loops = mesh.loops();
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int looptri_index : looptris.index_range()) {
const MLoopTri &looptri = looptris[looptri_index];
const int v0_loop = looptri.tri[0];
const int v1_loop = looptri.tri[1];
const int v2_loop = looptri.tri[2];
- const int v0_index = mesh.mloop[v0_loop].v;
- const int v1_index = mesh.mloop[v1_loop].v;
- const int v2_index = mesh.mloop[v2_loop].v;
- const float3 v0_pos = float3(mesh.mvert[v0_index].co);
- const float3 v1_pos = float3(mesh.mvert[v1_index].co);
- const float3 v2_pos = float3(mesh.mvert[v2_index].co);
+ const int v0_index = loops[v0_loop].v;
+ const int v1_index = loops[v1_loop].v;
+ const int v2_index = loops[v2_loop].v;
+ const float3 v0_pos = verts[v0_index].co;
+ const float3 v1_pos = verts[v1_index].co;
+ const float3 v2_pos = verts[v2_index].co;
float looptri_density_factor = 1.0f;
if (!density_factors.is_empty()) {
@@ -184,7 +185,7 @@ BLI_NOINLINE static void update_elimination_mask_for_close_points(
kdtree,
positions[i],
minimum_distance,
- [](void *user_data, int index, const float *UNUSED(co), float UNUSED(dist_sq)) {
+ [](void *user_data, int index, const float * /*co*/, float /*dist_sq*/) {
CallbackData &callback_data = *static_cast<CallbackData *>(user_data);
if (index != callback_data.index) {
callback_data.elimination_mask[index] = true;
@@ -202,8 +203,7 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors(
const Span<int> looptri_indices,
const MutableSpan<bool> elimination_mask)
{
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : bary_coords.index_range()) {
if (elimination_mask[i]) {
continue;
@@ -220,11 +220,11 @@ BLI_NOINLINE static void update_elimination_mask_based_on_density_factors(
const float v1_density_factor = std::max(0.0f, density_factors[v1_loop]);
const float v2_density_factor = std::max(0.0f, density_factors[v2_loop]);
- const float probablity = v0_density_factor * bary_coord.x + v1_density_factor * bary_coord.y +
- v2_density_factor * bary_coord.z;
+ const float probability = v0_density_factor * bary_coord.x + v1_density_factor * bary_coord.y +
+ v2_density_factor * bary_coord.z;
const float hash = noise::hash_float_to_float(bary_coord);
- if (hash > probablity) {
+ if (hash > probability) {
elimination_mask[i] = true;
}
}
@@ -283,15 +283,14 @@ BLI_NOINLINE static void interpolate_attribute(const Mesh &mesh,
}
BLI_NOINLINE static void propagate_existing_attributes(
- const MeshComponent &mesh_component,
+ const Mesh &mesh,
const Map<AttributeIDRef, AttributeKind> &attributes,
- GeometryComponent &point_component,
+ PointCloud &points,
const Span<float3> bary_coords,
const Span<int> looptri_indices)
{
- const Mesh &mesh = *mesh_component.get_for_read();
- const AttributeAccessor mesh_attributes = *mesh_component.attributes();
- MutableAttributeAccessor point_attributes = *point_component.attributes_for_write();
+ const AttributeAccessor mesh_attributes = mesh.attributes();
+ MutableAttributeAccessor point_attributes = points.attributes_for_write();
for (Map<AttributeIDRef, AttributeKind>::Item entry : attributes.items()) {
const AttributeIDRef attribute_id = entry.key;
@@ -326,44 +325,44 @@ struct AttributeOutputs {
};
} // namespace
-BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_component,
- PointCloudComponent &point_component,
+BLI_NOINLINE static void compute_attribute_outputs(const Mesh &mesh,
+ PointCloud &points,
const Span<float3> bary_coords,
const Span<int> looptri_indices,
const AttributeOutputs &attribute_outputs)
{
- MutableAttributeAccessor pointcloud_attributes = *point_component.attributes_for_write();
+ MutableAttributeAccessor point_attributes = points.attributes_for_write();
- SpanAttributeWriter<int> ids = pointcloud_attributes.lookup_or_add_for_write_only_span<int>(
+ SpanAttributeWriter<int> ids = point_attributes.lookup_or_add_for_write_only_span<int>(
"id", ATTR_DOMAIN_POINT);
SpanAttributeWriter<float3> normals;
SpanAttributeWriter<float3> rotations;
if (attribute_outputs.normal_id) {
- normals = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>(
+ normals = point_attributes.lookup_or_add_for_write_only_span<float3>(
attribute_outputs.normal_id.get(), ATTR_DOMAIN_POINT);
}
if (attribute_outputs.rotation_id) {
- rotations = pointcloud_attributes.lookup_or_add_for_write_only_span<float3>(
+ rotations = point_attributes.lookup_or_add_for_write_only_span<float3>(
attribute_outputs.rotation_id.get(), ATTR_DOMAIN_POINT);
}
- const Mesh &mesh = *mesh_component.get_for_read();
- const Span<MLoopTri> looptris{BKE_mesh_runtime_looptri_ensure(&mesh),
- BKE_mesh_runtime_looptri_len(&mesh)};
+ const Span<MVert> verts = mesh.verts();
+ const Span<MLoop> loops = mesh.loops();
+ const Span<MLoopTri> looptris = mesh.looptris();
for (const int i : bary_coords.index_range()) {
const int looptri_index = looptri_indices[i];
const MLoopTri &looptri = looptris[looptri_index];
const float3 &bary_coord = bary_coords[i];
- const int v0_index = mesh.mloop[looptri.tri[0]].v;
- const int v1_index = mesh.mloop[looptri.tri[1]].v;
- const int v2_index = mesh.mloop[looptri.tri[2]].v;
- const float3 v0_pos = float3(mesh.mvert[v0_index].co);
- const float3 v1_pos = float3(mesh.mvert[v1_index].co);
- const float3 v2_pos = float3(mesh.mvert[v2_index].co);
+ const int v0_index = loops[looptri.tri[0]].v;
+ const int v1_index = loops[looptri.tri[1]].v;
+ const int v2_index = loops[looptri.tri[2]].v;
+ const float3 v0_pos = verts[v0_index].co;
+ const float3 v1_pos = verts[v1_index].co;
+ const float3 v2_pos = verts[v2_index].co;
ids.span[i] = noise::hash(noise::hash_float(bary_coord), looptri_index);
@@ -380,25 +379,19 @@ BLI_NOINLINE static void compute_attribute_outputs(const MeshComponent &mesh_com
}
ids.finish();
-
- if (normals) {
- normals.finish();
- }
- if (rotations) {
- rotations.finish();
- }
+ normals.finish();
+ rotations.finish();
}
-static Array<float> calc_full_density_factors_with_selection(const MeshComponent &component,
+static Array<float> calc_full_density_factors_with_selection(const Mesh &mesh,
const Field<float> &density_field,
const Field<bool> &selection_field)
{
- const eAttrDomain attribute_domain = ATTR_DOMAIN_CORNER;
- GeometryComponentFieldContext field_context{component, attribute_domain};
- const int domain_size = component.attribute_domain_size(attribute_domain);
-
+ const eAttrDomain domain = ATTR_DOMAIN_CORNER;
+ const int domain_size = mesh.attributes().domain_size(domain);
Array<float> densities(domain_size, 0.0f);
+ bke::MeshFieldContext field_context{mesh, domain};
fn::FieldEvaluator evaluator{field_context, domain_size};
evaluator.set_selection(selection_field);
evaluator.add_with_destination(density_field, densities.as_mutable_span());
@@ -406,7 +399,7 @@ static Array<float> calc_full_density_factors_with_selection(const MeshComponent
return densities;
}
-static void distribute_points_random(const MeshComponent &component,
+static void distribute_points_random(const Mesh &mesh,
const Field<float> &density_field,
const Field<bool> &selection_field,
const int seed,
@@ -415,12 +408,11 @@ static void distribute_points_random(const MeshComponent &component,
Vector<int> &looptri_indices)
{
const Array<float> densities = calc_full_density_factors_with_selection(
- component, density_field, selection_field);
- const Mesh &mesh = *component.get_for_read();
+ mesh, density_field, selection_field);
sample_mesh_surface(mesh, 1.0f, densities, seed, positions, bary_coords, looptri_indices);
}
-static void distribute_points_poisson_disk(const MeshComponent &mesh_component,
+static void distribute_points_poisson_disk(const Mesh &mesh,
const float minimum_distance,
const float max_density,
const Field<float> &density_factor_field,
@@ -430,14 +422,13 @@ static void distribute_points_poisson_disk(const MeshComponent &mesh_component,
Vector<float3> &bary_coords,
Vector<int> &looptri_indices)
{
- const Mesh &mesh = *mesh_component.get_for_read();
sample_mesh_surface(mesh, max_density, {}, seed, positions, bary_coords, looptri_indices);
Array<bool> elimination_mask(positions.size(), false);
update_elimination_mask_for_close_points(positions, minimum_distance, elimination_mask);
const Array<float> density_factors = calc_full_density_factors_with_selection(
- mesh_component, density_factor_field, selection_field);
+ mesh, density_factor_field, selection_field);
update_elimination_mask_based_on_density_factors(
mesh, density_factors, bary_coords, looptri_indices, elimination_mask.as_mutable_span());
@@ -457,7 +448,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
return;
}
- const MeshComponent &mesh_component = *geometry_set.get_component_for_read<MeshComponent>();
+ const Mesh &mesh = *geometry_set.get_mesh_for_read();
Vector<float3> positions;
Vector<float3> bary_coords;
@@ -466,20 +457,15 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
switch (method) {
case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_RANDOM: {
const Field<float> density_field = params.get_input<Field<float>>("Density");
- distribute_points_random(mesh_component,
- density_field,
- selection_field,
- seed,
- positions,
- bary_coords,
- looptri_indices);
+ distribute_points_random(
+ mesh, density_field, selection_field, seed, positions, bary_coords, looptri_indices);
break;
}
case GEO_NODE_POINT_DISTRIBUTE_POINTS_ON_FACES_POISSON: {
const float minimum_distance = params.get_input<float>("Distance Min");
const float density_max = params.get_input<float>("Density Max");
const Field<float> density_factors_field = params.get_input<Field<float>>("Density Factor");
- distribute_points_poisson_disk(mesh_component,
+ distribute_points_poisson_disk(mesh,
minimum_distance,
density_max,
density_factors_field,
@@ -497,8 +483,7 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
}
PointCloud *pointcloud = BKE_pointcloud_new_nomain(positions.size());
- bke::MutableAttributeAccessor point_attributes = bke::pointcloud_attributes_for_write(
- *pointcloud);
+ bke::MutableAttributeAccessor point_attributes = pointcloud->attributes_for_write();
bke::SpanAttributeWriter<float3> point_positions =
point_attributes.lookup_or_add_for_write_only_span<float3>("position", ATTR_DOMAIN_POINT);
bke::SpanAttributeWriter<float> point_radii =
@@ -510,9 +495,6 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
geometry_set.replace_pointcloud(pointcloud);
- PointCloudComponent &point_component =
- geometry_set.get_component_for_write<PointCloudComponent>();
-
Map<AttributeIDRef, AttributeKind> attributes;
geometry_set.gather_attributes_for_propagation(
{GEO_COMPONENT_TYPE_MESH}, GEO_COMPONENT_TYPE_POINT_CLOUD, false, attributes);
@@ -520,19 +502,17 @@ static void point_distribution_calculate(GeometrySet &geometry_set,
/* Position is set separately. */
attributes.remove("position");
- propagate_existing_attributes(
- mesh_component, attributes, point_component, bary_coords, looptri_indices);
+ propagate_existing_attributes(mesh, attributes, *pointcloud, bary_coords, looptri_indices);
- compute_attribute_outputs(
- mesh_component, point_component, bary_coords, looptri_indices, attribute_outputs);
+ compute_attribute_outputs(mesh, *pointcloud, bary_coords, looptri_indices, attribute_outputs);
}
static void node_geo_exec(GeoNodeExecParams params)
{
GeometrySet geometry_set = params.extract_input<GeometrySet>("Mesh");
- const GeometryNodeDistributePointsOnFacesMode method =
- static_cast<GeometryNodeDistributePointsOnFacesMode>(params.node().custom1);
+ const GeometryNodeDistributePointsOnFacesMode method = GeometryNodeDistributePointsOnFacesMode(
+ params.node().custom1);
const int seed = params.get_input<int>("Seed") * 5383843;
const Field<bool> selection_field = params.extract_input<Field<bool>>("Selection");
@@ -545,6 +525,8 @@ static void node_geo_exec(GeoNodeExecParams params)
attribute_outputs.rotation_id = StrongAnonymousAttributeID("Rotation");
}
+ lazy_threading::send_hint();
+
geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) {
point_distribution_calculate(
geometry_set, selection_field, method, seed, attribute_outputs, params);