diff --git a/src/libslic3r/SLA/SupportPointGenerator.cpp b/src/libslic3r/SLA/SupportPointGenerator.cpp index 199b00d80e..ae138210f5 100644 --- a/src/libslic3r/SLA/SupportPointGenerator.cpp +++ b/src/libslic3r/SLA/SupportPointGenerator.cpp @@ -143,7 +143,10 @@ public: m_tree.build(indices); // consume indices } -private: + /// + /// Getter on used indices + /// + /// Current used Indices into m_points std::vector get_indices() const { std::vector indices = m_tree.get_nodes(); // copy // nodes in tree contain "max values for size_t" on unused leaf of tree, @@ -154,6 +157,7 @@ private: return indices; } }; +using NearPointss = std::vector; /// /// Intersection of line segment and circle @@ -209,7 +213,7 @@ Point intersection_line_circle(const Point &p1, const Point &p2, const Point &cn NearPoints create_near_points( const LayerParts &prev_layer_parts, const LayerPart &part, - std::vector &prev_grids + NearPointss &prev_grids ) { const LayerParts::const_iterator &prev_part_it = part.prev_parts.front(); size_t index_of_prev_part = prev_part_it - prev_layer_parts.begin(); @@ -480,25 +484,32 @@ Points sample_overhangs(const LayerPart& part, double dist2) { } coord_t calc_influence_radius(float z_distance, const SupportPointGeneratorConfig &config) { - float island_support_distance = config.support_curve.front().x() / config.density_relative; - if (z_distance >= island_support_distance) + float island_support_distance_sq = sqr(config.support_curve.front().x()); + if (!is_approx(config.density_relative, 1.f, 1e-4f)) // exist relative density + island_support_distance_sq /= config.density_relative; + float z_distance_sq = sqr(z_distance); + if (z_distance_sq >= island_support_distance_sq) return 0.f; // IMPROVE: use curve interpolation instead of sqrt(stored in config). - // shape of supported area before permanent supports is sphere with radius of island_support_distance - return static_cast(scale_( - std::sqrt(sqr(island_support_distance) - sqr(z_distance)) - )); + return static_cast(scale_(std::sqrt(island_support_distance_sq - z_distance_sq))); } void prepare_supports_for_layer(LayerSupportPoints &supports, float layer_z, - const SupportPointGeneratorConfig &config) { + const NearPointss& activ_points, const SupportPointGeneratorConfig &config) { auto set_radius = [&config](LayerSupportPoint &support, float radius) { if (!is_approx(config.density_relative, 1.f, 1e-4f)) // exist relative density - radius /= config.density_relative; + radius = std::sqrt(sqr(radius) / config.density_relative); support.current_radius = static_cast(scale_(radius)); }; + std::vector is_active(supports.size(), {false}); + for (const NearPoints& pts : activ_points) { + std::vector indices = pts.get_indices(); + for (size_t i : indices) + is_active[i] = true; + } + const std::vector& curve = config.support_curve; // calculate support area for each support point as radius // IMPROVE: use some offsets of previous supported island @@ -507,6 +518,9 @@ void prepare_supports_for_layer(LayerSupportPoints &supports, float layer_z, if (index + 1 >= curve.size()) continue; // already contain maximal radius + if (!is_active[&support - &supports.front()]) + continue; // Point is not used in any part of the current layer + // find current segment float diff_z = layer_z - support.pos.z(); if (diff_z < 0.) { @@ -1180,13 +1194,13 @@ LayerSupportPoints Slic3r::sla::generate_support_points( prepare_permanent_supports(data.permanent_supports, layers, config); // grid index == part in layer index - std::vector prev_grids; // same count as previous layer item size + NearPointss prev_grids; // same count as previous layer item size for (size_t layer_id = 0; layer_id < layers.size(); ++layer_id) { const Layer &layer = layers[layer_id]; - prepare_supports_for_layer(result, layer.print_z, config); + prepare_supports_for_layer(result, layer.print_z, prev_grids, config); // grid index == part in layer index - std::vector grids; + NearPointss grids; grids.reserve(layer.parts.size()); for (const LayerPart &part : layer.parts) { diff --git a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp index bec53205c4..37ed285a50 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoSlaSupports.cpp @@ -297,8 +297,10 @@ void GLGizmoSlaSupports::render_points(const Selection& selection) if (clipped) continue; - render_color = support_point.type == sla::SupportPointType::manual_add ? - manual_color : inactive_color; + render_color = + support_point.type == sla::SupportPointType::manual_add ? manual_color : + support_point.type == sla::SupportPointType::island ? island_color : + inactive_color; // First decide about the color of the point. if (m_editing_mode) { if (size_t(m_hover_id) == i) // ignore hover state unless editing mode is active @@ -307,7 +309,7 @@ void GLGizmoSlaSupports::render_points(const Selection& selection) render_color = selected_color; else if (m_lock_unique_islands) { render_color = support_point.type == sla::SupportPointType::island? - island_color : ColorRGBA{ 0.7f, 0.7f, 0.7f, 1.f }; + island_color : inactive_color; } } @@ -744,16 +746,9 @@ RENDER_AGAIN: const char *support_points_density = "support_points_density_relative"; float density = static_cast(get_config_options({support_points_density})[0])->value; float old_density = density; - wxString tooltip = _L( - "Divider for the supported radius\n" - "Smaller value means less point, supported radius is enlarged.\n" - "Larger value means more points, supported radius is reduced.\n" - "-- density percent ----- radisu change from 100 --\n" - "| 50 | 200 |\n" - "| 75 | 133 |\n" - "| 125 | 80 |\n" - "| 150 | 66 |\n" - "| 200 | 50 |\n"); + wxString tooltip = _L("Change amount of the generated support points.\n" + "Smaller value means less points and\n" + "larger value means more points."); if (m_imgui->slider_float("##density", &density, 50.f, 200.f, "%.f %%", 1.f, false, tooltip)){ if (density < 10.f) // not neccessary, but lower value seems pointless. Zero cause issues inside algorithms. density = 10.f;