Skip to content

Commit

Permalink
CURA-12207 Infill line printed multiple times with extra lines (#2150)
Browse files Browse the repository at this point in the history
  • Loading branch information
HellAholic authored Oct 21, 2024
2 parents dabbdac + 0f896bd commit 74e380a
Show file tree
Hide file tree
Showing 3 changed files with 87 additions and 50 deletions.
9 changes: 6 additions & 3 deletions include/utils/SVG.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ class SVG : NoCopy
private:
std::string toString(const Color color) const;
std::string toString(const ColorObject& color) const;
void handleFlush(const bool flush) const;

FILE* out_; // the output file
const AABB aabb_; // the boundary box to display
Expand Down Expand Up @@ -122,7 +123,7 @@ class SVG : NoCopy
*/
void writeLines(const std::vector<Point2LL>& polyline, const ColorObject color = Color::BLACK) const;

void writeLine(const Point2LL& a, const Point2LL& b, const ColorObject color = Color::BLACK, const double stroke_width = 1.0) const;
void writeLine(const Point2LL& a, const Point2LL& b, const ColorObject color = Color::BLACK, const double stroke_width = 1.0, const bool flush = true) const;

void writeArrow(const Point2LL& a, const Point2LL& b, const ColorObject color = Color::BLACK, const double stroke_width = 1.0, const double head_size = 5.0) const;

Expand All @@ -148,10 +149,12 @@ class SVG : NoCopy

void writePolygon(Polygon poly, const ColorObject color = Color::BLACK, const double stroke_width = 1.0, const bool flush = true) const;

void writePolylines(const Shape& polys, const ColorObject color = Color::BLACK, const double stroke_width = 1.0) const;
void writePolylines(const Shape& polys, const ColorObject color = Color::BLACK, const double stroke_width = 1.0, const bool flush = true) const;

void writePolyline(const Polygon& poly, const ColorObject color = Color::BLACK, const double stroke_width = 1.0) const;

void writePolyline(const Polyline& poly, const ColorObject color = Color::BLACK, const double stroke_width = 1.0, const bool flush = true) const;

/*!
* Draw variable-width paths into the image.
*
Expand Down Expand Up @@ -183,7 +186,7 @@ class SVG : NoCopy
* \param color The color to draw the line with.
* \param width_factor A multiplicative factor on the line width.
*/
void writeLine(const ExtrusionLine& line, const ColorObject color = Color::BLACK, const double width_factor = 1.0) const;
void writeLine(const ExtrusionLine& line, const ColorObject color = Color::BLACK, const double width_factor = 1.0, const bool flush = true) const;

/*!
* Draws a grid across the image and writes down coordinates.
Expand Down
83 changes: 48 additions & 35 deletions src/FffGcodeWriter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2064,14 +2064,10 @@ void getBestAngledLinesToSupportPoints(OpenLinesSet& result_lines, const Shape&
// We do this because supporting lines are hanging over air,
// and therefore print best as part of a continuous print move,
// rather than having a travel move before and after them.
//
// We also double-insert most lines, since that allows the
// elimination of all travel moves, and overlap isn't an issue
// because the lines are hanging.
void integrateSupportingLine(OpenLinesSet& infill_lines, const OpenPolyline& line_to_add)
{
// Returns the line index and the index of the point within an infill_line, null for no match found.
const auto findMatchingSegment = [&](Point2LL p) -> std::optional<std::tuple<int, int>>
const auto findMatchingSegment = [&](Point2LL p) -> std::optional<std::tuple<size_t, size_t>>
{
for (size_t i = 0; i < infill_lines.size(); ++i)
{
Expand Down Expand Up @@ -2101,59 +2097,76 @@ void integrateSupportingLine(OpenLinesSet& infill_lines, const OpenPolyline& lin
{
/* both ends intersect with the same line.
* If the inserted line has ends x, y
* and the original line was A--(x)--B---C--(y)--D
* Then the new line will be A--x--y--C---B--x--y--D
* Note that the middle part of the line is reversed.
* and the original line was ...--A--(x)--B--...--C--(y)--D--...
* Then the new lines will be ...--A--x--y--C--...--B--x
* And line y--D--...
* Note that some parts of the line are reversed,
* and the last one is completly split apart.
*/
OpenPolyline& old_line = infill_lines[front_line_index];
OpenPolyline new_line;
OpenPolyline new_line_start;
OpenPolyline new_line_end;
Point2LL x, y;
size_t x_index, y_index;
std::ptrdiff_t x_index, y_index;
if (front_point_index < back_point_index)
{
x = line_to_add.front();
y = line_to_add.back();
x_index = front_point_index;
y_index = back_point_index;
x_index = static_cast<std::ptrdiff_t>(front_point_index);
y_index = static_cast<std::ptrdiff_t>(back_point_index);
}
else
{
y = line_to_add.front();
x = line_to_add.back();
y_index = front_point_index;
x_index = back_point_index;
y_index = static_cast<std::ptrdiff_t>(front_point_index);
x_index = static_cast<std::ptrdiff_t>(back_point_index);
}
new_line.insert(new_line.end(), old_line.begin(), old_line.begin() + x_index);
new_line.push_back(x);
new_line.push_back(y);
new_line.insert(new_line.end(), old_line.rend() - y_index, old_line.rend() - x_index);
new_line.push_back(x);
new_line.push_back(y);
new_line.insert(new_line.end(), old_line.begin() + y_index, old_line.end());
old_line.setPoints(std::move(new_line.getPoints()));

new_line_start.insert(new_line_start.end(), old_line.begin(), old_line.begin() + x_index);
new_line_start.push_back(x);
new_line_start.push_back(y);
new_line_start.insert(new_line_start.end(), old_line.rend() - y_index, old_line.rend() - x_index);
new_line_start.push_back(x);

new_line_end.push_back(y);
new_line_end.insert(new_line_end.end(), old_line.begin() + y_index, old_line.end());

old_line.setPoints(std::move(new_line_start.getPoints()));
infill_lines.push_back(new_line_end);
}
else
{
/* Different lines
* If the line_to_add has ends [front, back]
* Existing line (intersects front): A B front C D E
* Other existing line (intersects back): M N back O P Q
* Result is Line: A B front back O P Q
* And line: M N back front C D E
* Existing line (intersects front): ...--A--(x)--B--...
* Other existing line (intersects back): ...--C--(y)--D--...
* Result is Line: ...--A--x--y--D--...
* And line: x--B--...
* And line: ...--C--y
*/
OpenPolyline& old_front = infill_lines[front_line_index];
OpenPolyline& old_back = infill_lines[back_line_index];
OpenPolyline new_front, new_back;
new_front.insert(new_front.end(), old_front.begin(), old_front.begin() + front_point_index);
new_front.push_back(line_to_add.front());
new_front.push_back(line_to_add.back());
new_front.insert(new_front.end(), old_back.begin() + back_point_index, old_back.end());
new_back.insert(new_back.end(), old_back.begin(), old_back.begin() + back_point_index);
new_back.push_back(line_to_add.back());
new_back.push_back(line_to_add.front());
new_back.insert(new_back.end(), old_front.begin() + front_point_index, old_front.end());
OpenPolyline full_line, new_front, new_back;
const Point2LL x = line_to_add.front();
const Point2LL y = line_to_add.back();
const auto x_index = static_cast<std::ptrdiff_t>(front_point_index);
const auto y_index = static_cast<std::ptrdiff_t>(back_point_index);

new_front.push_back(x);
new_front.insert(new_front.end(), old_front.begin() + x_index, old_front.end());

new_back.insert(new_back.end(), old_back.begin(), old_back.begin() + y_index);
new_back.push_back(y);

full_line.insert(full_line.end(), old_front.begin(), old_front.begin() + x_index);
full_line.push_back(x);
full_line.push_back(y);
full_line.insert(full_line.end(), old_back.begin() + y_index, old_back.end());

old_front.setPoints(std::move(new_front.getPoints()));
old_back.setPoints(std::move(new_back.getPoints()));
infill_lines.push_back(full_line);
}
}
else
Expand Down
45 changes: 33 additions & 12 deletions src/utils/SVG.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,14 @@ std::string SVG::toString(const ColorObject& color) const
}
}

void SVG::handleFlush(const bool flush) const
{
if (flush)
{
fflush(out_);
}
}


SVG::SVG(std::string filename, AABB aabb, Point2LL canvas_size, ColorObject background)
: SVG(
Expand Down Expand Up @@ -249,7 +257,7 @@ void SVG::writeLines(const std::vector<Point2LL>& polyline, const ColorObject co
fprintf(out_, "\" />\n"); // Write the end of the tag.
}

void SVG::writeLine(const Point2LL& a, const Point2LL& b, const ColorObject color, const double stroke_width) const
void SVG::writeLine(const Point2LL& a, const Point2LL& b, const ColorObject color, const double stroke_width, const bool flush) const
{
Point3D fa = transformF(a);
Point3D fb = transformF(b);
Expand All @@ -262,6 +270,8 @@ void SVG::writeLine(const Point2LL& a, const Point2LL& b, const ColorObject colo
static_cast<double>(fb.y_),
toString(color).c_str(),
static_cast<double>(stroke_width));

handleFlush(flush);
}

void SVG::writeArrow(const Point2LL& a, const Point2LL& b, const ColorObject color, const double stroke_width, const double head_size) const
Expand Down Expand Up @@ -342,10 +352,7 @@ void SVG::writePolygons(const Shape& polys, const ColorObject color, const doubl
writePolygon(poly, color, stroke_width, false);
}

if (flush)
{
fflush(out_);
}
handleFlush(flush);
}

void SVG::writePolygon(const Polygon poly, const ColorObject color, const double stroke_width, const bool flush) const
Expand Down Expand Up @@ -381,19 +388,18 @@ void SVG::writePolygon(const Polygon poly, const ColorObject color, const double
i++;
}

if (flush)
{
fflush(out_);
}
handleFlush(flush);
}


void SVG::writePolylines(const Shape& polys, const ColorObject color, const double stroke_width) const
void SVG::writePolylines(const Shape& polys, const ColorObject color, const double stroke_width, const bool flush) const
{
for (const Polygon& poly : polys)
{
writePolyline(poly, color, stroke_width);
writePolyline(poly, color, stroke_width, false);
}

handleFlush(flush);
}

void SVG::writePolyline(const Polygon& poly, const ColorObject color, const double stroke_width) const
Expand Down Expand Up @@ -427,6 +433,16 @@ void SVG::writePolyline(const Polygon& poly, const ColorObject color, const doub
}
}

void SVG::writePolyline(const Polyline& poly, const ColorObject color, const double stroke_width, const bool flush) const
{
for (auto iterator = poly.beginSegments(); iterator != poly.endSegments(); ++iterator)
{
writeLine((*iterator).start, (*iterator).end, color, stroke_width, false);
}

handleFlush(flush);
}

void SVG::writePaths(const std::vector<VariableWidthLines>& paths, const ColorObject color, const double width_factor) const
{
for (const VariableWidthLines& lines : paths)
Expand All @@ -443,7 +459,7 @@ void SVG::writeLines(const VariableWidthLines& lines, const ColorObject color, c
}
}

void SVG::writeLine(const ExtrusionLine& line, const ColorObject color, const double width_factor) const
void SVG::writeLine(const ExtrusionLine& line, const ColorObject color, const double width_factor, const bool flush) const
{
constexpr double minimum_line_width = 10; // Always have some width, otherwise some lines become completely invisible.
if (line.junctions_.empty()) // Only draw lines that have at least 2 junctions, otherwise they are degenerate.
Expand Down Expand Up @@ -481,6 +497,11 @@ void SVG::writeLine(const ExtrusionLine& line, const ColorObject color, const do

start_vertex = end_vertex; // For the next line segment.
}

if (flush)
{
fflush(out_);
}
}

void SVG::writeCoordinateGrid(const coord_t grid_size, const Color color, const double stroke_width, const double font_size) const
Expand Down

0 comments on commit 74e380a

Please sign in to comment.