2016-04-11 15:08:30 +00:00
|
|
|
#ifndef slic3r_FillBase_hpp_
|
|
|
|
#define slic3r_FillBase_hpp_
|
|
|
|
|
2016-11-02 08:00:26 +00:00
|
|
|
#include <assert.h>
|
2016-09-13 09:26:38 +00:00
|
|
|
#include <memory.h>
|
2016-04-11 15:08:30 +00:00
|
|
|
#include <float.h>
|
2016-09-13 09:26:38 +00:00
|
|
|
#include <stdint.h>
|
2020-04-22 08:54:11 +00:00
|
|
|
#include <stdexcept>
|
2016-04-11 15:08:30 +00:00
|
|
|
|
2019-01-21 16:51:37 +00:00
|
|
|
#include <type_traits>
|
|
|
|
|
2016-04-11 15:08:30 +00:00
|
|
|
#include "../libslic3r.h"
|
|
|
|
#include "../BoundingBox.hpp"
|
2020-09-14 14:27:55 +00:00
|
|
|
#include "../Exception.hpp"
|
2019-01-22 10:12:50 +00:00
|
|
|
#include "../Utils.hpp"
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
namespace Slic3r {
|
|
|
|
|
2019-10-16 15:43:43 +00:00
|
|
|
class ExPolygon;
|
2016-04-11 15:08:30 +00:00
|
|
|
class Surface;
|
2020-05-26 15:42:57 +00:00
|
|
|
enum InfillPattern : int;
|
2016-04-11 15:08:30 +00:00
|
|
|
|
2020-08-26 14:51:34 +00:00
|
|
|
namespace FillAdaptive_Internal {
|
|
|
|
struct Octree;
|
|
|
|
};
|
|
|
|
|
2020-09-14 14:27:55 +00:00
|
|
|
// Infill shall never fail, therefore the error is classified as RuntimeError, not SlicingError.
|
|
|
|
class InfillFailedException : public Slic3r::RuntimeError {
|
2020-04-22 08:54:11 +00:00
|
|
|
public:
|
2020-09-14 14:27:55 +00:00
|
|
|
InfillFailedException() : Slic3r::RuntimeError("Infill failed") {}
|
2020-04-22 08:54:11 +00:00
|
|
|
};
|
|
|
|
|
2016-04-11 15:08:30 +00:00
|
|
|
struct FillParams
|
|
|
|
{
|
2017-07-19 13:53:43 +00:00
|
|
|
bool full_infill() const { return density > 0.9999f; }
|
|
|
|
|
2016-10-27 15:03:57 +00:00
|
|
|
// Fill density, fraction in <0, 1>
|
2020-04-14 09:53:28 +00:00
|
|
|
float density { 0.f };
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
// Don't connect the fill lines around the inner perimeter.
|
2020-04-14 09:53:28 +00:00
|
|
|
bool dont_connect { false };
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
// Don't adjust spacing to fill the space evenly.
|
2020-04-14 09:53:28 +00:00
|
|
|
bool dont_adjust { true };
|
2016-04-11 15:08:30 +00:00
|
|
|
|
2020-04-25 06:15:04 +00:00
|
|
|
// Monotonous infill - strictly left to right for better surface quality of top infills.
|
|
|
|
bool monotonous { false };
|
|
|
|
|
2016-04-11 15:08:30 +00:00
|
|
|
// For Honeycomb.
|
|
|
|
// we were requested to complete each loop;
|
|
|
|
// in this case we don't try to make more continuous paths
|
2020-04-14 09:53:28 +00:00
|
|
|
bool complete { false };
|
2016-04-11 15:08:30 +00:00
|
|
|
};
|
2019-01-22 10:12:50 +00:00
|
|
|
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
class Fill
|
|
|
|
{
|
|
|
|
public:
|
|
|
|
// Index of the layer.
|
|
|
|
size_t layer_id;
|
2016-10-21 16:56:55 +00:00
|
|
|
// Z coordinate of the top print surface, in unscaled coordinates
|
2016-04-11 15:08:30 +00:00
|
|
|
coordf_t z;
|
|
|
|
// in unscaled coordinates
|
|
|
|
coordf_t spacing;
|
2017-07-19 13:53:43 +00:00
|
|
|
// infill / perimeter overlap, in unscaled coordinates
|
|
|
|
coordf_t overlap;
|
2016-04-11 15:08:30 +00:00
|
|
|
// in radians, ccw, 0 = East
|
|
|
|
float angle;
|
2016-10-27 15:03:57 +00:00
|
|
|
// In scaled coordinates. Maximum lenght of a perimeter segment connecting two infill lines.
|
2016-11-09 14:39:12 +00:00
|
|
|
// Used by the FillRectilinear2, FillGrid2, FillTriangles, FillStars and FillCubic.
|
2016-10-27 15:03:57 +00:00
|
|
|
// If left to zero, the links will not be limited.
|
|
|
|
coord_t link_max_length;
|
|
|
|
// In scaled coordinates. Used by the concentric infill pattern to clip the loops to create extrusion paths.
|
2016-04-11 15:08:30 +00:00
|
|
|
coord_t loop_clipping;
|
2016-10-27 15:03:57 +00:00
|
|
|
// In scaled coordinates. Bounding box of the 2D projection of the object.
|
2016-04-11 15:08:30 +00:00
|
|
|
BoundingBox bounding_box;
|
|
|
|
|
2020-09-10 14:53:08 +00:00
|
|
|
// Octree builds on mesh for usage in the adaptive cubic infill
|
2020-08-26 14:51:34 +00:00
|
|
|
FillAdaptive_Internal::Octree* adapt_fill_octree = nullptr;
|
|
|
|
|
2016-04-11 15:08:30 +00:00
|
|
|
public:
|
|
|
|
virtual ~Fill() {}
|
|
|
|
|
2016-10-16 21:13:43 +00:00
|
|
|
static Fill* new_from_type(const InfillPattern type);
|
2016-04-11 15:08:30 +00:00
|
|
|
static Fill* new_from_type(const std::string &type);
|
2019-09-04 14:11:16 +00:00
|
|
|
static bool use_bridge_flow(const InfillPattern type);
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
void set_bounding_box(const Slic3r::BoundingBox &bbox) { bounding_box = bbox; }
|
|
|
|
|
|
|
|
// Use bridge flow for the fill?
|
|
|
|
virtual bool use_bridge_flow() const { return false; }
|
|
|
|
|
|
|
|
// Do not sort the fill lines to optimize the print head path?
|
|
|
|
virtual bool no_sort() const { return false; }
|
|
|
|
|
|
|
|
// Perform the fill.
|
2016-09-13 09:26:38 +00:00
|
|
|
virtual Polylines fill_surface(const Surface *surface, const FillParams ¶ms);
|
2016-04-11 15:08:30 +00:00
|
|
|
|
|
|
|
protected:
|
|
|
|
Fill() :
|
|
|
|
layer_id(size_t(-1)),
|
2017-07-19 13:53:43 +00:00
|
|
|
z(0.),
|
|
|
|
spacing(0.),
|
|
|
|
// Infill / perimeter overlap.
|
|
|
|
overlap(0.),
|
2016-04-11 15:08:30 +00:00
|
|
|
// Initial angle is undefined.
|
|
|
|
angle(FLT_MAX),
|
2016-10-27 15:03:57 +00:00
|
|
|
link_max_length(0),
|
2016-04-11 15:08:30 +00:00
|
|
|
loop_clipping(0),
|
|
|
|
// The initial bounding box is empty, therefore undefined.
|
|
|
|
bounding_box(Point(0, 0), Point(-1, -1))
|
|
|
|
{}
|
|
|
|
|
2016-09-13 09:26:38 +00:00
|
|
|
// The expolygon may be modified by the method to avoid a copy.
|
|
|
|
virtual void _fill_surface_single(
|
2017-07-27 08:39:43 +00:00
|
|
|
const FillParams & /* params */,
|
|
|
|
unsigned int /* thickness_layers */,
|
|
|
|
const std::pair<float, Point> & /* direction */,
|
|
|
|
ExPolygon & /* expolygon */,
|
|
|
|
Polylines & /* polylines_out */) {};
|
2016-09-13 09:26:38 +00:00
|
|
|
|
2017-07-27 08:39:43 +00:00
|
|
|
virtual float _layer_angle(size_t idx) const { return (idx & 1) ? float(M_PI/2.) : 0; }
|
2016-09-13 09:26:38 +00:00
|
|
|
|
|
|
|
virtual std::pair<float, Point> _infill_direction(const Surface *surface) const;
|
|
|
|
|
2017-07-27 08:39:43 +00:00
|
|
|
public:
|
2019-12-02 14:01:52 +00:00
|
|
|
static void connect_infill(Polylines &&infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, double spacing, const FillParams ¶ms);
|
|
|
|
|
2017-07-27 08:39:43 +00:00
|
|
|
static coord_t _adjust_solid_spacing(const coord_t width, const coord_t distance);
|
|
|
|
|
2016-09-13 09:26:38 +00:00
|
|
|
// Align a coordinate to a grid. The coordinate may be negative,
|
|
|
|
// the aligned value will never be bigger than the original one.
|
|
|
|
static coord_t _align_to_grid(const coord_t coord, const coord_t spacing) {
|
|
|
|
// Current C++ standard defines the result of integer division to be rounded to zero,
|
|
|
|
// for both positive and negative numbers. Here we want to round down for negative
|
|
|
|
// numbers as well.
|
|
|
|
coord_t aligned = (coord < 0) ?
|
|
|
|
((coord - spacing + 1) / spacing) * spacing :
|
|
|
|
(coord / spacing) * spacing;
|
|
|
|
assert(aligned <= coord);
|
|
|
|
return aligned;
|
|
|
|
}
|
|
|
|
static Point _align_to_grid(Point coord, Point spacing)
|
2018-08-17 13:53:43 +00:00
|
|
|
{ return Point(_align_to_grid(coord(0), spacing(0)), _align_to_grid(coord(1), spacing(1))); }
|
2016-09-13 09:26:38 +00:00
|
|
|
static coord_t _align_to_grid(coord_t coord, coord_t spacing, coord_t base)
|
|
|
|
{ return base + _align_to_grid(coord - base, spacing); }
|
|
|
|
static Point _align_to_grid(Point coord, Point spacing, Point base)
|
2018-08-17 13:53:43 +00:00
|
|
|
{ return Point(_align_to_grid(coord(0), spacing(0), base(0)), _align_to_grid(coord(1), spacing(1), base(1))); }
|
2016-04-11 15:08:30 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
} // namespace Slic3r
|
|
|
|
|
|
|
|
#endif // slic3r_FillBase_hpp_
|