39 const int edges_num = verts_num == 2 ? 1 : verts_num < 2 ? 0 : loops_num / 2;
53 MutableSpan<float3> dst_positions = result->vert_positions_for_write();
54 for (
const int i : IndexRange(verts_num)) {
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)) {
119 loops.reinitialize(
len);
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;
143 if (
const Mesh *mesh = geometry_set.get_mesh()) {
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();
154 if (
const PointCloud *points = geometry_set.get_pointcloud()) {
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();
165 if (
const Curves *curves_id = geometry_set.get_curves()) {
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);
186 if (
const Mesh *mesh = geometry_set.get_mesh()) {
187 if (
const VArray varray = *mesh->attributes().lookup<
float3>(
"position")) {
188 varray.materialize(positions.as_mutable_span().slice(offset, varray.size()));
189 offset += varray.size();
193 if (
const PointCloud *points = geometry_set.get_pointcloud()) {
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();
200 if (
const Curves *curves_id = geometry_set.get_curves()) {
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);
207 return hull_from_bullet(geometry_set.get_mesh(), positions);
210static void convex_hull_grease_pencil(GeometrySet &geometry_set)
214 const GreasePencil &grease_pencil = *geometry_set.get_grease_pencil();
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) {
223 const Span<float3> positions_span = curves.evaluated_positions();
227 mesh_by_layer[layer_index] = hull_from_bullet(
nullptr, positions_span);
230 if (mesh_by_layer.is_empty()) {
237 if (instances ==
nullptr) {
239 instances_component.
replace(instances);
241 for (
Mesh *mesh : mesh_by_layer) {
254 geometry_set.replace_grease_pencil(
nullptr);
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();