39 const int edges_num = verts_num == 2 ? 1 : verts_num < 2 ? 0 : loops_num / 2;
58 if (original_index >= 0 && original_index < coords.
size()) {
61 if (mesh && original_index < mesh->verts_num) {
76 Array<int> corner_verts(loops_num);
77 Array<int> corner_edges(loops_num);
79 MutableSpan<int2> edges =
result->edges_for_write();
81 for (
const int i : IndexRange(loops_num)) {
86 corner_verts[i] = v_from;
89 edges[edge_index] =
int2(v_from, v_to);
93 corner_edges[i] = edge_index;
94 corner_edges[reverse_index] = edge_index;
100 edges[0] =
int2(0, 1);
108 MutableSpan<int> face_offsets =
result->face_offsets_for_write();
109 MutableSpan<int> mesh_corner_verts =
result->corner_verts_for_write();
110 MutableSpan<int> mesh_corner_edges =
result->corner_edges_for_write();
113 for (
const int i : IndexRange(faces_num)) {
123 for (
const int k : IndexRange(
len)) {
124 mesh_corner_verts[dst_corner] = corner_verts[loops[k]];
125 mesh_corner_edges[dst_corner] = corner_edges[loops[k]];
135static Mesh *compute_hull(
const GeometrySet &geometry_set)
141 Span<float3> positions_span;
145 if (
const VArray positions = *mesh->
attributes().lookup<
float3>(
"position")) {
146 if (positions.is_span()) {
148 positions_span = positions.get_internal_span();
150 total_num += positions.size();
156 if (
const VArray positions = *points->attributes().lookup<
float3>(
"position")) {
157 if (positions.is_span()) {
159 positions_span = positions.get_internal_span();
161 total_num += positions.size();
168 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
169 positions_span = curves.evaluated_positions();
170 total_num += positions_span.
size();
179 if (span_count == 1 &&
count == 1) {
180 return hull_from_bullet(geometry_set.
get_mesh(), positions_span);
183 Array<float3> positions(total_num);
188 varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
189 offset += varray.size();
194 if (
const VArray varray = *points->attributes().lookup<
float3>(
"position")) {
195 varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
196 offset += varray.size();
201 const bke::CurvesGeometry &curves = curves_id->geometry.wrap();
202 Span<float3> array = curves.evaluated_positions();
203 positions.as_mutable_span().slice(offset, array.
size()).copy_from(array);
204 offset += array.
size();
207 return hull_from_bullet(geometry_set.
get_mesh(), positions);
210static void convex_hull_grease_pencil(GeometrySet &geometry_set)
212 using namespace blender::bke::greasepencil;
215 Array<Mesh *> mesh_by_layer(grease_pencil.layers().size(),
nullptr);
217 for (
const int layer_index : grease_pencil.layers().index_range()) {
218 const Drawing *drawing = grease_pencil.get_eval_drawing(grease_pencil.layer(layer_index));
219 if (drawing ==
nullptr) {
222 const bke::CurvesGeometry &curves = drawing->
strokes();
227 mesh_by_layer[layer_index] = hull_from_bullet(
nullptr, positions_span);
230 if (mesh_by_layer.is_empty()) {
234 InstancesComponent &instances_component =
236 bke::Instances *instances = instances_component.
get_for_write();
237 if (instances ==
nullptr) {
238 instances =
new bke::Instances();
239 instances_component.
replace(instances);
241 for (
Mesh *mesh : mesh_by_layer) {
246 const int handle = instances->add_reference(bke::InstanceReference());
251 const int handle = instances->add_reference(bke::InstanceReference{temp_set});
266 Mesh *
mesh = compute_hull(geometry_set);
272 convex_hull_grease_pencil(geometry_set);
277 params.set_output(
"Convex Hull", std::move(geometry_set));
279 params.error_message_add(NodeWarningType::Error,
280 TIP_(
"Disabled, Blender was compiled without Bullet"));
281 params.set_default_remaining_outputs();