Skip to content

Commit

Permalink
[CURA-11597] fix duplicate support extrusions (#2062)
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Apr 18, 2024
2 parents 44a5ef6 + 5139274 commit 6d89383
Show file tree
Hide file tree
Showing 7 changed files with 49 additions and 23 deletions.
2 changes: 1 addition & 1 deletion include/infill/NoZigZagConnectorProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ class NoZigZagConnectorProcessor : public ZigzagConnectorProcessor
}

void registerVertex(const Point2LL& vertex);
void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index);
void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline);
void registerPolyFinished();
};

Expand Down
15 changes: 3 additions & 12 deletions include/infill/ZigzagConnectorProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ class ZigzagConnectorProcessor
* \param intersection The intersection
* \param scanline_index Index of the current scanline
*/
virtual void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index);
virtual void registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline);

/*!
* Handle the end of a polygon and prepare for the next.
Expand Down Expand Up @@ -166,17 +166,6 @@ class ZigzagConnectorProcessor
*/
bool shouldAddCurrentConnector(int start_scanline_idx, int end_scanline_idx) const;

/*!
* Checks whether two points are separated at least by "threshold" microns.
* If they are far away from each other enough, the line represented by the two points
* will be added; In case they are close, the second point will be set to be the same
* as the first and this line won't be added.
*
* \param first_point The first of the points
* \param second_point The second of the points
*/
void checkAndAddZagConnectorLine(Point2LL* first_point, Point2LL* second_point);

/*!
* Adds a Zag connector represented by the given points. The last line of the connector will not be
* added if the given connector is an end piece and "connected_endpieces" is not enabled.
Expand All @@ -186,6 +175,8 @@ class ZigzagConnectorProcessor
*/
void addZagConnector(std::vector<Point2LL>& points, bool is_endpiece);

bool handleConnectorTooCloseToSegment(const coord_t scanline_x, const coord_t min_distance_to_scanline);

protected:
const PointMatrix& rotation_matrix_; //!< The rotation matrix used to enforce the infill angle
Polygons& result_; //!< The result of the computation
Expand Down
6 changes: 3 additions & 3 deletions src/infill.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -746,12 +746,12 @@ void Infill::generateLinearBasedInfill(

for (int scanline_idx = scanline_idx0; scanline_idx != scanline_idx1 + direction; scanline_idx += direction)
{
int x = scanline_idx * line_distance + shift;
int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
const int x = scanline_idx * line_distance + shift;
const int y = p1.Y + (p0.Y - p1.Y) * (x - p1.X) / (p0.X - p1.X);
assert(scanline_idx - scanline_min_idx >= 0 && scanline_idx - scanline_min_idx < int(cut_list.size()) && "reading infill cutlist index out of bounds!");
cut_list[scanline_idx - scanline_min_idx].push_back(y);
Point2LL scanline_linesegment_intersection(x, y);
zigzag_connector_processor.registerScanlineSegmentIntersection(scanline_linesegment_intersection, scanline_idx);
zigzag_connector_processor.registerScanlineSegmentIntersection(scanline_linesegment_intersection, scanline_idx, line_distance / 4);
crossings_per_scanline[scanline_idx - min_scanline_index].emplace_back(scanline_linesegment_intersection, poly_idx, point_idx);
}
zigzag_connector_processor.registerVertex(p1);
Expand Down
2 changes: 1 addition & 1 deletion src/infill/NoZigZagConnectorProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ void NoZigZagConnectorProcessor::registerVertex(const Point2LL&)
// No need to add anything.
}

void NoZigZagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL&, int)
void NoZigZagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL&, int, coord_t)
{
// No need to add anything.
}
Expand Down
22 changes: 20 additions & 2 deletions src/infill/ZigzagConnectorProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,8 +83,26 @@ bool ZigzagConnectorProcessor::shouldAddCurrentConnector(int start_scanline_idx,
return should_add;
}

bool ZigzagConnectorProcessor::handleConnectorTooCloseToSegment(const coord_t scanline_x, const coord_t min_distance_to_scanline)
{
if (current_connector_.empty())
{
return false;
}
else
{
return std::find_if(
current_connector_.begin(),
current_connector_.end(),
[scanline_x, min_distance_to_scanline](const Point2LL& point)
{
return std::abs(point.X - scanline_x) >= min_distance_to_scanline;
})
== current_connector_.end();
}
}

void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index)
void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2LL& intersection, int scanline_index, coord_t min_distance_to_scanline)
{
if (is_first_connector_)
{
Expand All @@ -97,7 +115,7 @@ void ZigzagConnectorProcessor::registerScanlineSegmentIntersection(const Point2L
else
{
// add the current connector if needed
if (shouldAddCurrentConnector(last_connector_index_, scanline_index))
if (shouldAddCurrentConnector(last_connector_index_, scanline_index) && ! handleConnectorTooCloseToSegment(intersection.X, min_distance_to_scanline))
{
const bool is_this_endpiece = scanline_index == last_connector_index_;
current_connector_.push_back(intersection);
Expand Down
14 changes: 12 additions & 2 deletions src/skin.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#include "settings/types/Angle.h" //For the infill support angle.
#include "settings/types/Ratio.h"
#include "sliceDataStorage.h"
#include "utils/Simplify.h"
#include "utils/math.h"
#include "utils/polygonUtils.h"

Expand Down Expand Up @@ -465,9 +466,12 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
const LayerIndex mesh_min_layer = mesh.settings.get<size_t>("initial_bottom_layers");
const LayerIndex mesh_max_layer = mesh.layers.size() - 1 - mesh.settings.get<size_t>("top_layers");

const Simplify simplifier(mesh.settings.get<ExtruderTrain&>("infill_extruder_nr").settings_);

const auto infill_wall_count = mesh.settings.get<size_t>("infill_wall_line_count");
const auto infill_wall_width = mesh.settings.get<coord_t>("infill_line_width");
const auto infill_overlap = mesh.settings.get<coord_t>("infill_overlap_mm");
const auto is_connected = mesh.settings.get<bool>("zig_zaggify_infill") || mesh.settings.get<EFillMethod>("infill_pattern") == EFillMethod::ZIG_ZAG;
for (LayerIndex layer_idx = 0; layer_idx < static_cast<LayerIndex>(mesh.layers.size()); layer_idx++)
{ // loop also over layers which don't contain infill cause of bottom_ and top_layer to initialize their infill_area_per_combine_per_density
SliceLayer& layer = mesh.layers[layer_idx];
Expand All @@ -494,6 +498,7 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
continue;
}
Polygons less_dense_infill = infill_area; // one step less dense with each infill_step
Polygons sum_more_dense; // NOTE: Only used for zig-zag or connected fills.
for (size_t infill_step = 0; infill_step < max_infill_steps; infill_step++)
{
LayerIndex min_layer = layer_idx + infill_step * gradual_infill_step_layer_count + static_cast<size_t>(layer_skip_count);
Expand Down Expand Up @@ -526,11 +531,16 @@ void SkinInfillAreaComputation::generateGradualInfill(SliceMeshStorage& mesh)
part.infill_area_per_combine_per_density.emplace_back();
std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
const Polygons more_dense_infill = infill_area.difference(less_dense_infill);
infill_area_per_combine_current_density.push_back(more_dense_infill);
infill_area_per_combine_current_density.push_back(
simplifier.polygon(more_dense_infill.difference(sum_more_dense).offset(-infill_wall_width).offset(infill_wall_width)));
if (is_connected)
{
sum_more_dense = sum_more_dense.unionPolygons(more_dense_infill);
}
}
part.infill_area_per_combine_per_density.emplace_back();
std::vector<Polygons>& infill_area_per_combine_current_density = part.infill_area_per_combine_per_density.back();
infill_area_per_combine_current_density.push_back(infill_area);
infill_area_per_combine_current_density.push_back(simplifier.polygon(infill_area.difference(sum_more_dense).offset(-infill_wall_width).offset(infill_wall_width)));
part.infill_area_own = std::nullopt; // clear infill_area_own, it's not needed any more.
assert(! part.infill_area_per_combine_per_density.empty() && "infill_area_per_combine_per_density is now initialized");
}
Expand Down
11 changes: 9 additions & 2 deletions src/support.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -187,6 +187,8 @@ void AreaSupport::generateGradualSupport(SliceDataStorage& storage)
const size_t max_density_steps = infill_extruder.settings_.get<size_t>("gradual_support_infill_steps");

const coord_t wall_width = infill_extruder.settings_.get<coord_t>("support_line_width");
const bool is_connected = infill_extruder.settings_.get<bool>("zig_zaggify_infill") || infill_extruder.settings_.get<EFillMethod>("infill_pattern") == EFillMethod::ZIG_ZAG;
const Simplify simplifier(infill_extruder.settings_);

// no early-out for this function; it needs to initialize the [infill_area_per_combine_per_density]
double layer_skip_count{ 8.0 }; // skip every so many layers as to ignore small gaps in the model making computation more easy
Expand Down Expand Up @@ -234,6 +236,7 @@ void AreaSupport::generateGradualSupport(SliceDataStorage& storage)

// calculate density areas for this island
Polygons less_dense_support = infill_area; // one step less dense with each density_step
Polygons sum_more_dense; // NOTE: Only used for zig-zag or connected fills.
for (unsigned int density_step = 0; density_step < max_density_steps; ++density_step)
{
LayerIndex actual_min_layer{ layer_nr + density_step * gradual_support_step_layer_count + static_cast<LayerIndex::value_type>(layer_skip_count) };
Expand Down Expand Up @@ -292,12 +295,16 @@ void AreaSupport::generateGradualSupport(SliceDataStorage& storage)
support_infill_part.infill_area_per_combine_per_density_.emplace_back();
std::vector<Polygons>& support_area_current_density = support_infill_part.infill_area_per_combine_per_density_.back();
const Polygons more_dense_support = infill_area.difference(less_dense_support);
support_area_current_density.push_back(more_dense_support);
support_area_current_density.push_back(simplifier.polygon(more_dense_support.difference(sum_more_dense)));
if (is_connected)
{
sum_more_dense = sum_more_dense.unionPolygons(more_dense_support);
}
}

support_infill_part.infill_area_per_combine_per_density_.emplace_back();
std::vector<Polygons>& support_area_current_density = support_infill_part.infill_area_per_combine_per_density_.back();
support_area_current_density.push_back(infill_area);
support_area_current_density.push_back(simplifier.polygon(infill_area.difference(sum_more_dense)));

assert(support_infill_part.infill_area_per_combine_per_density_.size() != 0 && "support_infill_part.infill_area_per_combine_per_density should now be initialized");
#ifdef DEBUG
Expand Down

0 comments on commit 6d89383

Please sign in to comment.