Changeset View
Changeset View
Standalone View
Standalone View
source/blender/nodes/geometry/nodes/node_geo_convex_hull.cc
| Show First 20 Lines • Show All 221 Lines • ▼ Show 20 Lines | for (const SplinePtr &spline : curve.splines()) { | ||||
| positions.as_mutable_span().slice(offset, array.size()).copy_from(array); | positions.as_mutable_span().slice(offset, array.size()).copy_from(array); | ||||
| offset += array.size(); | offset += array.size(); | ||||
| } | } | ||||
| } | } | ||||
| return hull_from_bullet(geometry_set.get_mesh_for_read(), positions); | return hull_from_bullet(geometry_set.get_mesh_for_read(), positions); | ||||
| } | } | ||||
| /* Since only positions are read from the instances, this can be used as an internal optimization | |||||
| * to avoid the cost of realizing instances before the node. But disable this for now, since | |||||
| * re-enabling that optimization will be a separate step. */ | |||||
| # if 0 | |||||
| static void read_positions(const GeometryComponent &component, | static void read_positions(const GeometryComponent &component, | ||||
| Span<float4x4> transforms, | Span<float4x4> transforms, | ||||
| Vector<float3> *r_coords) | Vector<float3> *r_coords) | ||||
| { | { | ||||
| GVArray_Typed<float3> positions = component.attribute_get_for_read<float3>( | GVArray_Typed<float3> positions = component.attribute_get_for_read<float3>( | ||||
| "position", ATTR_DOMAIN_POINT, {0, 0, 0}); | "position", ATTR_DOMAIN_POINT, {0, 0, 0}); | ||||
| /* NOTE: could use convex hull operation here to | /* NOTE: could use convex hull operation here to | ||||
| * cut out some vertices, before accumulating, | * cut out some vertices, before accumulating, | ||||
| * but can also be done by the user beforehand. */ | * but can also be done by the user beforehand. */ | ||||
| Show All 19 Lines | for (const SplinePtr &spline : curve.splines()) { | ||||
| for (const float4x4 &transform : transforms) { | for (const float4x4 &transform : transforms) { | ||||
| for (const float3 &position : positions) { | for (const float3 &position : positions) { | ||||
| r_coords->append(transform * position); | r_coords->append(transform * position); | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| #endif /* WITH_BULLET */ | static Mesh *convex_hull_from_instances(const GeometrySet &geometry_set) | ||||
| static void geo_node_convex_hull_exec(GeoNodeExecParams params) | |||||
| { | { | ||||
| GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | |||||
| #ifdef WITH_BULLET | |||||
| Mesh *mesh = nullptr; | |||||
| if (geometry_set.has_instances()) { | |||||
| Vector<GeometryInstanceGroup> set_groups; | Vector<GeometryInstanceGroup> set_groups; | ||||
| bke::geometry_set_gather_instances(geometry_set, set_groups); | bke::geometry_set_gather_instances(geometry_set, set_groups); | ||||
| Vector<float3> coords; | Vector<float3> coords; | ||||
| for (const GeometryInstanceGroup &set_group : set_groups) { | for (const GeometryInstanceGroup &set_group : set_groups) { | ||||
| const GeometrySet &set = set_group.geometry_set; | const GeometrySet &set = set_group.geometry_set; | ||||
| Span<float4x4> transforms = set_group.transforms; | Span<float4x4> transforms = set_group.transforms; | ||||
| if (set.has_pointcloud()) { | if (set.has_pointcloud()) { | ||||
| read_positions(*set.get_component_for_read<PointCloudComponent>(), transforms, &coords); | read_positions(*set.get_component_for_read<PointCloudComponent>(), transforms, &coords); | ||||
| } | } | ||||
| if (set.has_mesh()) { | if (set.has_mesh()) { | ||||
| read_positions(*set.get_component_for_read<MeshComponent>(), transforms, &coords); | read_positions(*set.get_component_for_read<MeshComponent>(), transforms, &coords); | ||||
| } | } | ||||
| if (set.has_curve()) { | if (set.has_curve()) { | ||||
| read_curve_positions(*set.get_curve_for_read(), transforms, &coords); | read_curve_positions(*set.get_curve_for_read(), transforms, &coords); | ||||
| } | } | ||||
| } | } | ||||
| mesh = hull_from_bullet(nullptr, coords); | return hull_from_bullet(nullptr, coords); | ||||
| } | |||||
| else { | |||||
| mesh = compute_hull(geometry_set); | |||||
| } | } | ||||
| params.set_output("Convex Hull", GeometrySet::create_with_mesh(mesh)); | # endif | ||||
| #endif /* WITH_BULLET */ | |||||
| static void geo_node_convex_hull_exec(GeoNodeExecParams params) | |||||
| { | |||||
| GeometrySet geometry_set = params.extract_input<GeometrySet>("Geometry"); | |||||
| #ifdef WITH_BULLET | |||||
| geometry_set.modify_geometry_sets([&](GeometrySet &geometry_set) { | |||||
| Mesh *mesh = compute_hull(geometry_set); | |||||
| geometry_set.replace_mesh(mesh); | |||||
| geometry_set.keep_only({GEO_COMPONENT_TYPE_MESH, GEO_COMPONENT_TYPE_INSTANCES}); | |||||
| }); | |||||
| params.set_output("Convex Hull", std::move(geometry_set)); | |||||
| #else | #else | ||||
| params.error_message_add(NodeWarningType::Error, | params.error_message_add(NodeWarningType::Error, | ||||
| TIP_("Disabled, Blender was compiled without Bullet")); | TIP_("Disabled, Blender was compiled without Bullet")); | ||||
| params.set_output("Convex Hull", geometry_set); | params.set_output("Convex Hull", geometry_set); | ||||
| #endif /* WITH_BULLET */ | #endif /* WITH_BULLET */ | ||||
| } | } | ||||
| } // namespace blender::nodes | } // namespace blender::nodes | ||||
| Show All 10 Lines | |||||