Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CURA-12207 Infill line printed multiple times with extra lines #2150

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Loading