From 42a7f2b1d873907b96502889d319c7056eee2f38 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Hejl?= <hejl.lukas@gmail.com>
Date: Wed, 26 Aug 2020 16:51:34 +0200
Subject: [PATCH] Preparation for new infill

---
 src/libslic3r/CMakeLists.txt        |  2 ++
 src/libslic3r/Fill/Fill.cpp         |  1 +
 src/libslic3r/Fill/FillAdaptive.cpp | 19 +++++++++++
 src/libslic3r/Fill/FillAdaptive.hpp | 53 +++++++++++++++++++++++++++++
 src/libslic3r/Fill/FillBase.cpp     |  2 ++
 src/libslic3r/Fill/FillBase.hpp     |  6 ++++
 src/libslic3r/Print.hpp             |  8 +++++
 src/libslic3r/PrintConfig.cpp       |  2 ++
 src/libslic3r/PrintConfig.hpp       |  3 +-
 9 files changed, 95 insertions(+), 1 deletion(-)
 create mode 100644 src/libslic3r/Fill/FillAdaptive.cpp
 create mode 100644 src/libslic3r/Fill/FillAdaptive.hpp

diff --git a/src/libslic3r/CMakeLists.txt b/src/libslic3r/CMakeLists.txt
index 290b8953c..afec75974 100644
--- a/src/libslic3r/CMakeLists.txt
+++ b/src/libslic3r/CMakeLists.txt
@@ -46,6 +46,8 @@ add_library(libslic3r STATIC
     Fill/Fill.hpp
     Fill/Fill3DHoneycomb.cpp
     Fill/Fill3DHoneycomb.hpp
+    Fill/FillAdaptive.cpp
+    Fill/FillAdaptive.hpp
     Fill/FillBase.cpp
     Fill/FillBase.hpp
     Fill/FillConcentric.cpp
diff --git a/src/libslic3r/Fill/Fill.cpp b/src/libslic3r/Fill/Fill.cpp
index 3c16527f0..c948df400 100644
--- a/src/libslic3r/Fill/Fill.cpp
+++ b/src/libslic3r/Fill/Fill.cpp
@@ -345,6 +345,7 @@ void Layer::make_fills()
         f->layer_id = this->id();
         f->z 		= this->print_z;
         f->angle 	= surface_fill.params.angle;
+        f->adapt_fill_octree = this->object()->adaptiveInfillOctree();
 
         // calculate flow spacing for infill pattern generation
         bool using_internal_flow = ! surface_fill.surface.is_solid() && ! surface_fill.params.flow.bridge;
diff --git a/src/libslic3r/Fill/FillAdaptive.cpp b/src/libslic3r/Fill/FillAdaptive.cpp
new file mode 100644
index 000000000..cb1138598
--- /dev/null
+++ b/src/libslic3r/Fill/FillAdaptive.cpp
@@ -0,0 +1,19 @@
+#include "../ClipperUtils.hpp"
+#include "../ExPolygon.hpp"
+#include "../Surface.hpp"
+
+#include "FillAdaptive.hpp"
+
+namespace Slic3r {
+
+void FillAdaptive::_fill_surface_single(
+    const FillParams                &params, 
+    unsigned int                     thickness_layers,
+    const std::pair<float, Point>   &direction, 
+    ExPolygon                       &expolygon, 
+    Polylines                       &polylines_out)
+{
+
+}
+
+} // namespace Slic3r
diff --git a/src/libslic3r/Fill/FillAdaptive.hpp b/src/libslic3r/Fill/FillAdaptive.hpp
new file mode 100644
index 000000000..e0a97a1b9
--- /dev/null
+++ b/src/libslic3r/Fill/FillAdaptive.hpp
@@ -0,0 +1,53 @@
+#ifndef slic3r_FillAdaptive_hpp_
+#define slic3r_FillAdaptive_hpp_
+
+#include "FillBase.hpp"
+
+namespace Slic3r {
+
+namespace FillAdaptive_Internal
+{
+    struct CubeProperties
+    {
+        double edge_length;     // Lenght of edge of a cube
+        double height;          // Height of rotated cube (standing on the corner)
+        double diagonal_length; // Length of diagonal of a cube a face
+        double line_z_distance; // Defines maximal distance from a center of a cube on Z axis on which lines will be created
+        double line_xy_distance;// Defines maximal distance from a center of a cube on X and Y axis on which lines will be created
+    };
+
+    struct Cube
+    {
+        Vec3d center;
+        size_t depth;
+        CubeProperties properties;
+        std::vector<Cube*> children;
+    };
+
+    struct Octree
+    {
+        Cube *root_cube;
+        Vec3d origin;
+    };
+}; // namespace FillAdaptive_Internal
+
+class FillAdaptive : public Fill
+{
+public:
+    virtual ~FillAdaptive() {}
+
+protected:
+    virtual Fill* clone() const { return new FillAdaptive(*this); };
+	virtual void _fill_surface_single(
+	    const FillParams                &params, 
+	    unsigned int                     thickness_layers,
+	    const std::pair<float, Point>   &direction, 
+	    ExPolygon                       &expolygon, 
+	    Polylines                       &polylines_out);
+
+	virtual bool no_sort() const { return true; }
+};
+
+} // namespace Slic3r
+
+#endif // slic3r_FillAdaptive_hpp_
diff --git a/src/libslic3r/Fill/FillBase.cpp b/src/libslic3r/Fill/FillBase.cpp
index c760218c0..c1f38dad5 100644
--- a/src/libslic3r/Fill/FillBase.cpp
+++ b/src/libslic3r/Fill/FillBase.cpp
@@ -16,6 +16,7 @@
 #include "FillRectilinear.hpp"
 #include "FillRectilinear2.hpp"
 #include "FillRectilinear3.hpp"
+#include "FillAdaptive.hpp"
 
 namespace Slic3r {
 
@@ -37,6 +38,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
     case ipArchimedeanChords:   return new FillArchimedeanChords();
     case ipHilbertCurve:        return new FillHilbertCurve();
     case ipOctagramSpiral:      return new FillOctagramSpiral();
+    case ipAdaptiveCubic:       return new FillAdaptive();
     default: throw std::invalid_argument("unknown type");
     }
 }
diff --git a/src/libslic3r/Fill/FillBase.hpp b/src/libslic3r/Fill/FillBase.hpp
index 2e9b64735..9f70b69e0 100644
--- a/src/libslic3r/Fill/FillBase.hpp
+++ b/src/libslic3r/Fill/FillBase.hpp
@@ -19,6 +19,10 @@ class ExPolygon;
 class Surface;
 enum InfillPattern : int;
 
+namespace FillAdaptive_Internal {
+    struct Octree;
+};
+
 class InfillFailedException : public std::runtime_error {
 public:
     InfillFailedException() : std::runtime_error("Infill failed") {}
@@ -69,6 +73,8 @@ public:
     // In scaled coordinates. Bounding box of the 2D projection of the object.
     BoundingBox bounding_box;
 
+    FillAdaptive_Internal::Octree* adapt_fill_octree = nullptr;
+
 public:
     virtual ~Fill() {}
 
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index 05929dd2e..5f8613a2d 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -25,6 +25,10 @@ enum class SlicingMode : uint32_t;
 class Layer;
 class SupportLayer;
 
+namespace FillAdaptive_Internal {
+    struct Octree;
+};
+
 // Print step IDs for keeping track of the print state.
 enum PrintStep {
     psSkirt, 
@@ -191,6 +195,7 @@ public:
     void project_and_append_custom_enforcers(std::vector<ExPolygons>& enforcers) const { project_and_append_custom_supports(FacetSupportType::ENFORCER, enforcers); }
     void project_and_append_custom_blockers(std::vector<ExPolygons>& blockers) const { project_and_append_custom_supports(FacetSupportType::BLOCKER, blockers); }
 
+    FillAdaptive_Internal::Octree* adaptiveInfillOctree() { return m_adapt_fill_octree; }
 private:
     // to be called from Print only.
     friend class Print;
@@ -232,6 +237,7 @@ private:
     void discover_horizontal_shells();
     void combine_infill();
     void _generate_support_material();
+    void prepare_adaptive_infill_data();
 
     // XYZ in scaled coordinates
     Vec3crd									m_size;
@@ -252,6 +258,8 @@ private:
     // so that next call to make_perimeters() performs a union() before computing loops
     bool                    				m_typed_slices = false;
 
+    FillAdaptive_Internal::Octree*          m_adapt_fill_octree = nullptr;
+
     std::vector<ExPolygons> slice_region(size_t region_id, const std::vector<float> &z, SlicingMode mode) const;
     std::vector<ExPolygons> slice_modifiers(size_t region_id, const std::vector<float> &z) const;
     std::vector<ExPolygons> slice_volumes(const std::vector<float> &z, SlicingMode mode, const std::vector<const ModelVolume*> &volumes) const;
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index 3401dcc02..a855e4b1a 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -881,6 +881,7 @@ void PrintConfigDef::init_fff_params()
     def->enum_values.push_back("hilbertcurve");
     def->enum_values.push_back("archimedeanchords");
     def->enum_values.push_back("octagramspiral");
+    def->enum_values.push_back("adaptivecubic");
     def->enum_labels.push_back(L("Rectilinear"));
     def->enum_labels.push_back(L("Grid"));
     def->enum_labels.push_back(L("Triangles"));
@@ -894,6 +895,7 @@ void PrintConfigDef::init_fff_params()
     def->enum_labels.push_back(L("Hilbert Curve"));
     def->enum_labels.push_back(L("Archimedean Chords"));
     def->enum_labels.push_back(L("Octagram Spiral"));
+    def->enum_labels.push_back(L("Adaptive Cubic"));
     def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipStars));
 
     def = this->add("first_layer_acceleration", coFloat);
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index c4566c983..abd19a7fe 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -39,7 +39,7 @@ enum AuthorizationType {
 
 enum InfillPattern : int {
     ipRectilinear, ipMonotonous, ipGrid, ipTriangles, ipStars, ipCubic, ipLine, ipConcentric, ipHoneycomb, ip3DHoneycomb,
-    ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipCount,
+    ipGyroid, ipHilbertCurve, ipArchimedeanChords, ipOctagramSpiral, ipAdaptiveCubic, ipCount,
 };
 
 enum class IroningType {
@@ -139,6 +139,7 @@ template<> inline const t_config_enum_values& ConfigOptionEnum<InfillPattern>::g
         keys_map["hilbertcurve"]        = ipHilbertCurve;
         keys_map["archimedeanchords"]   = ipArchimedeanChords;
         keys_map["octagramspiral"]      = ipOctagramSpiral;
+        keys_map["adaptivecubic"]       = ipAdaptiveCubic;
     }
     return keys_map;
 }