Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/prusa3d/PrusaSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLukáš Hejl <hejl.lukas@gmail.com>2022-08-10 17:25:15 +0300
committerLukáš Hejl <hejl.lukas@gmail.com>2022-08-12 10:48:34 +0300
commite838acdcd18e3d6ce889f73b75548a986018dfdc (patch)
tree62f8dcbba7bd320899d6814ecf4b3463ae8ba1b2
parent4d19eb9ace6201193b8719117a4abbab499ef933 (diff)
Added a lot of debugging outputs (SVG) into SkeletalTrapezoidation.
-rw-r--r--src/libslic3r/Arachne/SkeletalTrapezoidation.cpp164
-rw-r--r--src/libslic3r/Arachne/SkeletalTrapezoidation.hpp7
-rw-r--r--src/libslic3r/PerimeterGenerator.cpp35
-rw-r--r--src/libslic3r/SVG.cpp3
4 files changed, 185 insertions, 24 deletions
diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
index fbd3379d5..03677b5db 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.cpp
@@ -22,8 +22,6 @@
#define SKELETAL_TRAPEZOIDATION_BEAD_SEARCH_MAX 1000 //A limit to how long it'll keep searching for adjacent beads. Increasing will re-use beadings more often (saving performance), but search longer for beading (costing performance).
-//#define ARACHNE_DEBUG
-
namespace boost::polygon {
template<> struct geometry_concept<Slic3r::Arachne::PolygonsSegmentIndex>
@@ -46,6 +44,71 @@ template<> struct segment_traits<Slic3r::Arachne::PolygonsSegmentIndex>
namespace Slic3r::Arachne
{
+#ifdef ARACHNE_DEBUG
+static void export_graph_to_svg(const std::string &path,
+ SkeletalTrapezoidationGraph &graph,
+ const Polygons &polys,
+ const std::vector<std::shared_ptr<LineJunctions>> &edge_junctions = {},
+ const bool beat_count = true,
+ const bool transition_middles = true,
+ const bool transition_ends = true)
+{
+ const std::vector<std::string> colors = {"blue", "cyan", "red", "orange", "magenta", "pink", "purple", "green", "yellow"};
+ coordf_t stroke_width = scale_(0.03);
+ BoundingBox bbox = get_extents(polys);
+ for (const auto &node : graph.nodes)
+ bbox.merge(node.p);
+
+ bbox.offset(scale_(1.));
+
+ ::Slic3r::SVG svg(path.c_str(), bbox);
+ for (const auto &line : to_lines(polys))
+ svg.draw(line, "gray", stroke_width);
+
+ for (const auto &edge : graph.edges)
+ svg.draw(Line(edge.from->p, edge.to->p), (edge.data.centralIsSet() && edge.data.isCentral()) ? "blue" : "cyan", stroke_width);
+
+ for (const auto &line_junction : edge_junctions)
+ for (const auto &extrusion_junction : *line_junction)
+ svg.draw(extrusion_junction.p, "orange", coord_t(stroke_width * 2.));
+
+ if (beat_count) {
+ for (const auto &node : graph.nodes) {
+ svg.draw(node.p, "red", coord_t(stroke_width * 1.6));
+ svg.draw_text(node.p, std::to_string(node.data.bead_count).c_str(), "black", 1);
+ }
+ }
+
+ if (transition_middles) {
+ for (auto &edge : graph.edges) {
+ if (std::shared_ptr<std::list<SkeletalTrapezoidationEdge::TransitionMiddle>> transitions = edge.data.getTransitions(); transitions) {
+ for (auto &transition : *transitions) {
+ Line edge_line = Line(edge.to->p, edge.from->p);
+ double edge_length = edge_line.length();
+ Point pt = edge_line.a + (edge_line.vector().cast<double>() * (double(transition.pos) / edge_length)).cast<coord_t>();
+ svg.draw(pt, "magenta", coord_t(stroke_width * 1.5));
+ svg.draw_text(pt, std::to_string(transition.lower_bead_count).c_str(), "black", 1);
+ }
+ }
+ }
+ }
+
+ if (transition_ends) {
+ for (auto &edge : graph.edges) {
+ if (std::shared_ptr<std::list<SkeletalTrapezoidationEdge::TransitionEnd>> transitions = edge.data.getTransitionEnds(); transitions) {
+ for (auto &transition : *transitions) {
+ Line edge_line = Line(edge.to->p, edge.from->p);
+ double edge_length = edge_line.length();
+ Point pt = edge_line.a + (edge_line.vector().cast<double>() * (double(transition.pos) / edge_length)).cast<coord_t>();
+ svg.draw(pt, transition.is_lower_end ? "green" : "lime", coord_t(stroke_width * 1.5));
+ svg.draw_text(pt, std::to_string(transition.lower_bead_count).c_str(), "black", 1);
+ }
+ }
+ }
+ }
+}
+#endif
+
SkeletalTrapezoidation::node_t& SkeletalTrapezoidation::makeNode(vd_t::vertex_type& vd_node, Point p)
{
auto he_node_it = vd_node_to_he_node.find(&vd_node);
@@ -489,6 +552,10 @@ inline static void rotate_back_skeletal_trapezoidation_graph_after_fix(SkeletalT
void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
{
+#ifdef ARACHNE_DEBUG
+ this->outline = polys;
+#endif
+
// Check self intersections.
assert([&polys]() -> bool {
EdgeGrid::Grid grid;
@@ -517,7 +584,7 @@ void SkeletalTrapezoidation::constructFromPolygons(const Polygons& polys)
Geometry::VoronoiDiagram voronoi_diagram;
construct_voronoi(segments.begin(), segments.end(), &voronoi_diagram);
-#ifdef ARACHNE_DEBUG
+#ifdef ARACHNE_DEBUG_VORONOI
{
static int iRun = 0;
dump_voronoi_to_svg(debug_out_path("arachne_voronoi-diagram-%d.svg", iRun++).c_str(), voronoi_diagram, to_points(polys), to_lines(polys));
@@ -694,45 +761,62 @@ void SkeletalTrapezoidation::separatePointyQuadEndNodes()
// vvvvvvvvvvvvvvvvvvvvv
//
-#if 0
-static void export_graph_to_svg(const std::string &path, const SkeletalTrapezoidationGraph &graph, const Polygons &polys)
+void SkeletalTrapezoidation::generateToolpaths(std::vector<VariableWidthLines> &generated_toolpaths, bool filter_outermost_central_edges)
{
- const std::vector<std::string> colors = {"blue", "cyan", "red", "orange", "magenta", "pink", "purple", "green", "yellow"};
- coordf_t stroke_width = scale_(0.05);
- BoundingBox bbox;
- for (const auto &node : graph.nodes)
- bbox.merge(node.p);
-
- bbox.offset(scale_(1.));
- ::Slic3r::SVG svg(path.c_str(), bbox);
- for (const auto &line : to_lines(polys))
- svg.draw(line, "red", stroke_width);
-
- for (const auto &edge : graph.edges)
- svg.draw(Line(edge.from->p, edge.to->p), "cyan", scale_(0.01));
-}
+#ifdef ARACHNE_DEBUG
+ static int iRun = 0;
#endif
-void SkeletalTrapezoidation::generateToolpaths(std::vector<VariableWidthLines> &generated_toolpaths, bool filter_outermost_central_edges)
-{
p_generated_toolpaths = &generated_toolpaths;
updateIsCentral();
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-updateIsCentral-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
filterCentral(central_filter_dist);
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-filterCentral-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
if (filter_outermost_central_edges)
filterOuterCentral();
updateBeadCount();
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-updateBeadCount-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
filterNoncentralRegions();
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-filterNoncentralRegions-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
generateTransitioningRibs();
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateTransitioningRibs-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
generateExtraRibs();
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateExtraRibs-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
generateSegments();
+
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateSegments-final-%d.svg", iRun), this->graph, this->outline);
+#endif
+
+#ifdef ARACHNE_DEBUG
+ ++iRun;
+#endif
}
void SkeletalTrapezoidation::updateIsCentral()
@@ -944,11 +1028,24 @@ void SkeletalTrapezoidation::generateTransitioningRibs()
filterTransitionMids();
+#ifdef ARACHNE_DEBUG
+ static int iRun = 0;
+ export_graph_to_svg(debug_out_path("ST-generateTransitioningRibs-mids-%d.svg", iRun++), this->graph, this->outline);
+#endif
+
ptr_vector_t<std::list<TransitionEnd>> edge_transition_ends; // We only map the half edge in the upward direction. mapped items are not sorted
generateAllTransitionEnds(edge_transition_ends);
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateTransitioningRibs-ends-%d.svg", iRun++), this->graph, this->outline);
+#endif
+
applyTransitions(edge_transition_ends);
// Note that the shared pointer lists will be out of scope and thus destroyed here, since the remaining refs are weak_ptr.
+
+#ifdef ARACHNE_DEBUG
+ ++iRun;
+#endif
}
@@ -1668,17 +1765,38 @@ void SkeletalTrapezoidation::generateSegments()
}
}
}
-
+
+#ifdef ARACHNE_DEBUG
+ static int iRun = 0;
+ export_graph_to_svg(debug_out_path("ST-generateSegments-before-propagation-%d.svg", iRun), this->graph, this->outline);
+#endif
+
propagateBeadingsUpward(upward_quad_mids, node_beadings);
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateSegments-upward-propagation-%d.svg", iRun), this->graph, this->outline);
+#endif
+
propagateBeadingsDownward(upward_quad_mids, node_beadings);
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateSegments-downward-propagation-%d.svg", iRun), this->graph, this->outline);
+#endif
+
ptr_vector_t<LineJunctions> edge_junctions; // junctions ordered high R to low R
generateJunctions(node_beadings, edge_junctions);
+#ifdef ARACHNE_DEBUG
+ export_graph_to_svg(debug_out_path("ST-generateSegments-junctions-%d.svg", iRun), this->graph, this->outline, edge_junctions);
+#endif
+
connectJunctions(edge_junctions);
-
+
generateLocalMaximaSingleBeads();
+
+#ifdef ARACHNE_DEBUG
+ ++iRun;
+#endif
}
SkeletalTrapezoidation::edge_t* SkeletalTrapezoidation::getQuadMaxRedgeTo(edge_t* quad_start_edge)
diff --git a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
index 83065cf87..819b71367 100644
--- a/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
+++ b/src/libslic3r/Arachne/SkeletalTrapezoidation.hpp
@@ -20,6 +20,9 @@
#include "SkeletalTrapezoidationGraph.hpp"
#include "../Geometry/Voronoi.hpp"
+//#define ARACHNE_DEBUG
+//#define ARACHNE_DEBUG_VORONOI
+
namespace Slic3r::Arachne
{
@@ -123,6 +126,10 @@ public:
*/
void generateToolpaths(std::vector<VariableWidthLines> &generated_toolpaths, bool filter_outermost_central_edges = false);
+#ifdef ARACHNE_DEBUG
+ Polygons outline;
+#endif
+
protected:
/*!
* Auxiliary for referencing one transition along an edge which may contain multiple transitions
diff --git a/src/libslic3r/PerimeterGenerator.cpp b/src/libslic3r/PerimeterGenerator.cpp
index dafa850cd..830d48571 100644
--- a/src/libslic3r/PerimeterGenerator.cpp
+++ b/src/libslic3r/PerimeterGenerator.cpp
@@ -12,6 +12,13 @@
#include <stack>
#include <unordered_map>
+//#define ARACHNE_DEBUG
+
+#ifdef ARACHNE_DEBUG
+#include "SVG.hpp"
+#include "Utils.hpp"
+#endif
+
namespace Slic3r {
ExtrusionPaths thick_polyline_to_extrusion_paths(const ThickPolyline &thick_polyline, ExtrusionRole role, const Flow &flow, const float tolerance, const float merge_tolerance)
@@ -537,6 +544,27 @@ static ExtrusionEntityCollection traverse_extrusions(const PerimeterGenerator &p
return extrusion_coll;
}
+#ifdef ARACHNE_DEBUG
+static void export_perimeters_to_svg(const std::string &path, const Polygons &contours, const std::vector<Arachne::VariableWidthLines> &perimeters, const ExPolygons &infill_area)
+{
+ coordf_t stroke_width = scale_(0.03);
+ BoundingBox bbox = get_extents(contours);
+ bbox.offset(scale_(1.));
+ ::Slic3r::SVG svg(path.c_str(), bbox);
+
+ svg.draw(infill_area, "cyan");
+
+ for (const Arachne::VariableWidthLines &perimeter : perimeters)
+ for (const Arachne::ExtrusionLine &extrusion_line : perimeter) {
+ ThickPolyline thick_polyline = to_thick_polyline(extrusion_line);
+ svg.draw({thick_polyline}, "green", "blue", stroke_width);
+ }
+
+ for (const Line &line : to_lines(contours))
+ svg.draw(line, "red", stroke_width);
+}
+#endif
+
// Thanks, Cura developers, for implementing an algorithm for generating perimeters with variable width (Arachne) that is based on the paper
// "A framework for adaptive width control of dense contour-parallel toolpaths in fused deposition modeling"
void PerimeterGenerator::process_arachne()
@@ -578,6 +606,13 @@ void PerimeterGenerator::process_arachne()
std::vector<Arachne::VariableWidthLines> perimeters = wallToolPaths.getToolPaths();
loop_number = int(perimeters.size()) - 1;
+#ifdef ARACHNE_DEBUG
+ {
+ static int iRun = 0;
+ export_perimeters_to_svg(debug_out_path("arachne-perimeters-%d-%d.svg", layer_id, iRun++), to_polygons(last), perimeters, union_ex(wallToolPaths.getInnerContour()));
+ }
+#endif
+
// All closed ExtrusionLine should have the same the first and the last point.
// But in rare cases, Arachne produce ExtrusionLine marked as closed but without
// equal the first and the last point.
diff --git a/src/libslic3r/SVG.cpp b/src/libslic3r/SVG.cpp
index 4928d5433..d68301e74 100644
--- a/src/libslic3r/SVG.cpp
+++ b/src/libslic3r/SVG.cpp
@@ -287,9 +287,10 @@ void SVG::draw_text(const Point &pt, const char *text, const char *color, const
void SVG::draw_legend(const Point &pt, const char *text, const char *color, const coordf_t font_size)
{
fprintf(this->f,
- R"(<circle cx="%f" cy="%f" r="10" fill="%s"/>)",
+ R"(<circle cx="%f" cy="%f" r="%f" fill="%s"/>)",
to_svg_x(float(pt.x() - origin.x())),
to_svg_y(float(pt.y() - origin.y())),
+ font_size,
color);
fprintf(this->f,
R"(<text x="%f" y="%f" font-family="sans-serif" font-size="%fpx" fill="%s">%s</text>)",