26 b.add_output<
decl::Geometry>(
"Convex Hull").propagate_all_instance_attributes();
39 const int edges_num = verts_num == 2 ? 1 : verts_num < 2 ? 0 : loops_num / 2;
63 dst_positions[
i] = coords[original_index];
71 Array<int> corner_verts(loops_num);
72 Array<int> corner_edges(loops_num);
74 MutableSpan<int2> edges =
result->edges_for_write();
76 for (
const int i : IndexRange(loops_num)) {
81 corner_verts[
i] = v_from;
84 edges[edge_index] =
int2(v_from, v_to);
88 corner_edges[
i] = edge_index;
89 corner_edges[reverse_index] = edge_index;
95 edges[0] =
int2(0, 1);
103 MutableSpan<int> face_offsets =
result->face_offsets_for_write();
104 MutableSpan<int> mesh_corner_verts =
result->corner_verts_for_write();
105 MutableSpan<int> mesh_corner_edges =
result->corner_edges_for_write();
108 for (
const int i : IndexRange(faces_num)) {
118 for (
const int k : IndexRange(
len)) {
119 mesh_corner_verts[dst_corner] = corner_verts[loops[k]];
120 mesh_corner_edges[dst_corner] = corner_edges[loops[k]];
130static Mesh *compute_hull(
const GeometrySet &geometry_set)
136 Span<float3> positions_span;
140 if (
const VArray positions = *mesh->
attributes().lookup<
float3>(
"position")) {
141 if (positions.is_span()) {
143 positions_span = positions.get_internal_span();
145 total_num += positions.size();
151 if (
const VArray positions = *points->attributes().lookup<
float3>(
"position")) {
152 if (positions.is_span()) {
154 positions_span = positions.get_internal_span();
156 total_num += positions.size();
163 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
164 positions_span = curves.evaluated_positions();
165 total_num += positions_span.
size();
174 if (span_count == 1 &&
count == 1) {
175 return hull_from_bullet(geometry_set.
get_mesh(), positions_span);
178 Array<float3> positions(total_num);
183 varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
184 offset += varray.size();
189 if (
const VArray varray = *points->attributes().lookup<
float3>(
"position")) {
190 varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
191 offset += varray.size();
196 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
197 Span<float3> array = curves.evaluated_positions();
198 positions.as_mutable_span().slice(offset, array.
size()).copy_from(array);
199 offset += array.
size();
202 return hull_from_bullet(geometry_set.
get_mesh(), positions);
205static void convex_hull_grease_pencil(GeometrySet &geometry_set)
207 using namespace blender::bke::greasepencil;
210 Array<Mesh *> mesh_by_layer(grease_pencil.layers().size(),
nullptr);
212 for (
const int layer_index : grease_pencil.layers().index_range()) {
213 const Drawing *drawing = grease_pencil.get_eval_drawing(grease_pencil.layer(layer_index));
214 if (drawing ==
nullptr) {
217 const bke::CurvesGeometry &curves = drawing->
strokes();
222 mesh_by_layer[layer_index] = hull_from_bullet(
nullptr, positions_span);
225 if (mesh_by_layer.is_empty()) {
229 InstancesComponent &instances_component =
231 bke::Instances *instances = instances_component.
get_for_write();
232 if (instances ==
nullptr) {
233 instances =
new bke::Instances();
234 instances_component.
replace(instances);
236 for (
Mesh *mesh : mesh_by_layer) {
241 const int handle = instances->add_reference(bke::InstanceReference());
246 const int handle = instances->add_reference(bke::InstanceReference{temp_set});
261 Mesh *
mesh = compute_hull(geometry_set);
267 convex_hull_grease_pencil(geometry_set);
272 params.set_output(
"Convex Hull", std::move(geometry_set));
275 TIP_(
"Disabled, Blender was compiled without Bullet"));
276 params.set_default_remaining_outputs();
286 "Create a mesh that encloses all points in the input geometry with the smallest number of "