From c0d21bd2b496bf8b6393cb395cfce169bd857c20 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= <hejl.lukas@gmail.com>
Date: Thu, 27 Aug 2020 01:59:35 +0200
Subject: [PATCH] Polylines merging

---
 src/libslic3r/Fill/FillAdaptive.cpp | 84 ++++++++++++++++++++++++-----
 src/libslic3r/Fill/FillAdaptive.hpp |  4 +-
 2 files changed, 75 insertions(+), 13 deletions(-)

diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp
index ae067e659..adc6c0c6f 100644
--- a/src/libslic3r/Fill/FillAdaptive.cpp
+++ b/src/libslic3r/Fill/FillAdaptive.cpp
@@ -15,18 +15,54 @@ void FillAdaptive::_fill_surface_single(
     ExPolygon                       &expolygon, 
     Polylines                       &polylines_out)
 {
-    Polylines infill_polylines;
+    std::vector<Polylines> infill_polylines(3);
     this->generate_polylines(this->adapt_fill_octree->root_cube, this->z, this->adapt_fill_octree->origin, infill_polylines);
 
-    // Crop all polylines
-    polylines_out = intersection_pl(infill_polylines, to_polygons(expolygon));
+    for (Polylines &infill_polyline : infill_polylines) {
+        // Crop all polylines
+        infill_polyline = intersection_pl(infill_polyline, to_polygons(expolygon));
+        polylines_out.insert(polylines_out.end(), infill_polyline.begin(), infill_polyline.end());
+    }
+
+#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
+    {
+        static int iRuna = 0;
+        BoundingBox bbox_svg = this->bounding_box;
+        {
+            ::Slic3r::SVG svg(debug_out_path("FillAdaptive-%d.svg", iRuna), bbox_svg);
+            for (const Polyline &polyline : polylines_out)
+            {
+                for (const Line &line : polyline.lines())
+                {
+                    Point from = line.a;
+                    Point to = line.b;
+                    Point diff = to - from;
+
+                    float shrink_length = scale_(0.4);
+                    float line_slope = (float)diff.y() / diff.x();
+                    float shrink_x = shrink_length / (float)std::sqrt(1.0 + (line_slope * line_slope));
+                    float shrink_y = line_slope * shrink_x;
+
+                    to.x() -= shrink_x;
+                    to.y() -= shrink_y;
+                    from.x() += shrink_x;
+                    from.y() += shrink_y;
+
+                    svg.draw(Line(from, to));
+                }
+            }
+        }
+
+        iRuna++;
+    }
+#endif /* SLIC3R_DEBUG */
 }
 
 void FillAdaptive::generate_polylines(
         FillAdaptive_Internal::Cube *cube,
         double z_position,
         const Vec3d &origin,
-        Polylines &polylines_out)
+        std::vector<Polylines> &polylines_out)
 {
     using namespace FillAdaptive_Internal;
 
@@ -52,7 +88,7 @@ void FillAdaptive::generate_polylines(
 
         float rotation_angle = Geometry::deg2rad(120.0);
 
-        for (int dir_idx = 0; dir_idx < 3; dir_idx++)
+        for (int i = 0; i < 3; i++)
         {
             Vec3d offset = cube->center - origin;
             Point from_abs(from), to_abs(to);
@@ -62,7 +98,8 @@ void FillAdaptive::generate_polylines(
             to_abs.x() += scale_(offset.x());
             to_abs.y() += scale_(offset.y());
 
-            polylines_out.push_back(Polyline(from_abs, to_abs));
+//            polylines_out[i].push_back(Polyline(from_abs, to_abs));
+            this->merge_polylines(polylines_out[i], Line(from_abs, to_abs));
 
             from.rotate(rotation_angle);
             to.rotate(rotation_angle);
@@ -75,6 +112,35 @@ void FillAdaptive::generate_polylines(
     }
 }
 
+void FillAdaptive::merge_polylines(Polylines &polylines, const Line &new_line)
+{
+    int eps = scale_(0.10);
+    bool modified = false;
+
+    for (Polyline &polyline : polylines)
+    {
+        if (std::abs(new_line.a.x() - polyline.points[1].x()) < eps && std::abs(new_line.a.y() - polyline.points[1].y()) < eps)
+        {
+            polyline.points[1].x() = new_line.b.x();
+            polyline.points[1].y() = new_line.b.y();
+            modified = true;
+        }
+
+        if (std::abs(new_line.b.x() - polyline.points[0].x()) < eps && std::abs(new_line.b.y() - polyline.points[0].y()) < eps)
+        {
+            polyline.points[0].x() = new_line.a.x();
+            polyline.points[0].y() = new_line.a.y();
+            modified = true;
+        }
+    }
+
+    if(!modified)
+    {
+        polylines.emplace_back(Polyline(new_line.a, new_line.b));
+    }
+}
+
+
 FillAdaptive_Internal::Octree* FillAdaptive::build_octree(
     TriangleMesh &triangleMesh,
     coordf_t line_spacing,
@@ -145,12 +211,6 @@ void FillAdaptive::expand_cube(
 
     for (const Vec3d &child_center : child_centers) {
         Vec3d child_center_transformed = cube->center + rotation_matrix * (child_center * (cube->properties.edge_length / 4));
-        Vec3d closest_point = Vec3d::Zero();
-        size_t closest_triangle_idx = 0;
-
-        double distance_squared = AABBTreeIndirect::squared_distance_to_indexed_triangle_set(
-                triangleMesh.its.vertices, triangleMesh.its.indices, distanceTree, child_center_transformed,
-                closest_triangle_idx,closest_point);
 
         if(AABBTreeIndirect::is_any_triangle_in_radius(triangleMesh.its.vertices, triangleMesh.its.indices, distanceTree, child_center_transformed, cube_radius_squared)) {
             cube->children.push_back(new Cube{child_center_transformed, cube->depth - 1, cubes_properties[cube->depth - 1]});
diff --git a/src/libslic3r/Fill/FillAdaptive.hpp b/src/libslic3r/Fill/FillAdaptive.hpp
index 9e1a196af..b2f4e37b1 100644
--- a/src/libslic3r/Fill/FillAdaptive.hpp
+++ b/src/libslic3r/Fill/FillAdaptive.hpp
@@ -54,7 +54,9 @@ protected:
 
 	virtual bool no_sort() const { return true; }
 
-    void generate_polylines(FillAdaptive_Internal::Cube *cube, double z_position, const Vec3d &origin, Polylines &polylines_out);
+    void generate_polylines(FillAdaptive_Internal::Cube *cube, double z_position, const Vec3d &origin, std::vector<Polylines> &polylines_out);
+
+    void merge_polylines(Polylines &polylines, const Line &new_line);
 
 public:
     static FillAdaptive_Internal::Octree* build_octree(