GPv3: Convex Hull node

We create one convex hull per layer, following what we do for instances.

This is covered as part of the design in #113602, and as such not
commented on the code itself.

Part of #113602.

Pull Request: https://projects.blender.org/blender/blender/pulls/113788
This commit is contained in:
Dalai Felinto
2023-10-16 22:16:34 +02:00
parent 4fe903bef7
commit dd8d3ec27b

View File

@@ -7,6 +7,8 @@
#include "DNA_pointcloud_types.h"
#include "BKE_curves.hh"
#include "BKE_grease_pencil.hh"
#include "BKE_instances.hh"
#include "BKE_material.h"
#include "BKE_mesh.hh"
@@ -207,6 +209,53 @@ static Mesh *compute_hull(const GeometrySet &geometry_set)
return hull_from_bullet(geometry_set.get_mesh(), positions);
}
static void convex_hull_grease_pencil(GeometrySet &geometry_set)
{
using namespace blender::bke::greasepencil;
const GreasePencil &grease_pencil = *geometry_set.get_grease_pencil();
Array<Mesh *> mesh_by_layer(grease_pencil.layers().size(), nullptr);
for (const int layer_index : grease_pencil.layers().index_range()) {
const Drawing *drawing = get_eval_grease_pencil_layer_drawing(grease_pencil, layer_index);
if (drawing == nullptr) {
continue;
}
const bke::CurvesGeometry &curves = drawing->strokes();
const Span<float3> positions_span = curves.evaluated_positions();
if (positions_span.is_empty()) {
continue;
}
mesh_by_layer[layer_index] = hull_from_bullet(nullptr, positions_span);
}
if (mesh_by_layer.is_empty()) {
return;
}
InstancesComponent &instances_component =
geometry_set.get_component_for_write<InstancesComponent>();
bke::Instances *instances = instances_component.get_for_write();
if (instances == nullptr) {
instances = new bke::Instances();
instances_component.replace(instances);
}
for (Mesh *mesh : mesh_by_layer) {
if (!mesh) {
/* Add an empty reference so the number of layers and instances match.
* This makes it easy to reconstruct the layers afterwards and keep their attributes.
* Although in this particular case we don't propagate the attributes. */
const int handle = instances->add_reference(bke::InstanceReference());
instances->add_instance(handle, float4x4::identity());
continue;
}
GeometrySet temp_set = GeometrySet::from_mesh(mesh);
const int handle = instances->add_reference(bke::InstanceReference{temp_set});
instances->add_instance(handle, float4x4::identity());
}
geometry_set.replace_grease_pencil(nullptr);
}
#endif /* WITH_BULLET */
static void node_geo_exec(GeoNodeExecParams params)
@@ -221,6 +270,9 @@ static void node_geo_exec(GeoNodeExecParams params)
geometry::debug_randomize_mesh_order(mesh);
}
geometry_set.replace_mesh(mesh);
if (geometry_set.has_grease_pencil()) {
convex_hull_grease_pencil(geometry_set);
}
geometry_set.keep_only_during_modify({GeometryComponent::Type::Mesh});
});