mirror of
https://github.com/OrcaSlicer/OrcaSlicer.git
synced 2026-07-27 21:02:23 +00:00
Add 2D honeycomb infill pattern (#9483)
* Add 2D honeycomb infill pattern * Reverted change of 2D lattice infill void area estimation --------- Co-authored-by: Noisyfox <timemanager.rick@gmail.com>
This commit is contained in:
@@ -69,6 +69,9 @@ struct SurfaceFillParams
|
||||
float lattice_angle_1 = 0.f;
|
||||
float lattice_angle_2 = 0.f;
|
||||
|
||||
// Params for 2D honeycomb
|
||||
float infill_overhang_angle = 60.f;
|
||||
|
||||
bool operator<(const SurfaceFillParams &rhs) const {
|
||||
#define RETURN_COMPARE_NON_EQUAL(KEY) if (this->KEY < rhs.KEY) return true; if (this->KEY > rhs.KEY) return false;
|
||||
#define RETURN_COMPARE_NON_EQUAL_TYPED(TYPE, KEY) if (TYPE(this->KEY) < TYPE(rhs.KEY)) return true; if (TYPE(this->KEY) > TYPE(rhs.KEY)) return false;
|
||||
@@ -97,31 +100,33 @@ struct SurfaceFillParams
|
||||
RETURN_COMPARE_NON_EQUAL(solid_infill_speed);
|
||||
RETURN_COMPARE_NON_EQUAL(lattice_angle_1);
|
||||
RETURN_COMPARE_NON_EQUAL(lattice_angle_2);
|
||||
RETURN_COMPARE_NON_EQUAL(infill_overhang_angle);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool operator==(const SurfaceFillParams &rhs) const {
|
||||
return this->extruder == rhs.extruder &&
|
||||
this->pattern == rhs.pattern &&
|
||||
this->spacing == rhs.spacing &&
|
||||
this->overlap == rhs.overlap &&
|
||||
this->angle == rhs.angle &&
|
||||
this->rotate_angle == rhs.rotate_angle &&
|
||||
this->bridge == rhs.bridge &&
|
||||
this->bridge_angle == rhs.bridge_angle &&
|
||||
this->density == rhs.density &&
|
||||
// this->dont_adjust == rhs.dont_adjust &&
|
||||
this->anchor_length == rhs.anchor_length &&
|
||||
this->anchor_length_max == rhs.anchor_length_max &&
|
||||
this->flow == rhs.flow &&
|
||||
this->extrusion_role == rhs.extrusion_role &&
|
||||
this->sparse_infill_speed == rhs.sparse_infill_speed &&
|
||||
this->top_surface_speed == rhs.top_surface_speed &&
|
||||
this->solid_infill_speed == rhs.solid_infill_speed &&
|
||||
this->lattice_angle_1 == rhs.lattice_angle_1 &&
|
||||
this->lattice_angle_2 == rhs.lattice_angle_2;
|
||||
}
|
||||
bool operator==(const SurfaceFillParams &rhs) const {
|
||||
return this->extruder == rhs.extruder &&
|
||||
this->pattern == rhs.pattern &&
|
||||
this->spacing == rhs.spacing &&
|
||||
this->overlap == rhs.overlap &&
|
||||
this->angle == rhs.angle &&
|
||||
this->rotate_angle == rhs.rotate_angle &&
|
||||
this->bridge == rhs.bridge &&
|
||||
this->bridge_angle == rhs.bridge_angle &&
|
||||
this->density == rhs.density &&
|
||||
// this->dont_adjust == rhs.dont_adjust &&
|
||||
this->anchor_length == rhs.anchor_length &&
|
||||
this->anchor_length_max == rhs.anchor_length_max &&
|
||||
this->flow == rhs.flow &&
|
||||
this->extrusion_role == rhs.extrusion_role &&
|
||||
this->sparse_infill_speed == rhs.sparse_infill_speed &&
|
||||
this->top_surface_speed == rhs.top_surface_speed &&
|
||||
this->solid_infill_speed == rhs.solid_infill_speed &&
|
||||
this->lattice_angle_1 == rhs.lattice_angle_1 &&
|
||||
this->lattice_angle_2 == rhs.lattice_angle_2 &&
|
||||
this->infill_overhang_angle == rhs.infill_overhang_angle;
|
||||
}
|
||||
};
|
||||
|
||||
struct SurfaceFill {
|
||||
@@ -622,6 +627,7 @@ std::vector<SurfaceFill> group_fills(const Layer &layer)
|
||||
params.density = float(region_config.sparse_infill_density);
|
||||
params.lattice_angle_1 = region_config.lattice_angle_1;
|
||||
params.lattice_angle_2 = region_config.lattice_angle_2;
|
||||
params.infill_overhang_angle = region_config.infill_overhang_angle;
|
||||
|
||||
if (surface.is_solid()) {
|
||||
params.density = 100.f;
|
||||
@@ -966,6 +972,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
params.layer_height = layerm->layer()->height;
|
||||
params.lattice_angle_1 = surface_fill.params.lattice_angle_1;
|
||||
params.lattice_angle_2 = surface_fill.params.lattice_angle_2;
|
||||
params.infill_overhang_angle = surface_fill.params.infill_overhang_angle;
|
||||
|
||||
// BBS
|
||||
params.flow = surface_fill.params.flow;
|
||||
@@ -1046,6 +1053,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
|
||||
case ipLine:
|
||||
case ipConcentric:
|
||||
case ipHoneycomb:
|
||||
case ip2DHoneycomb:
|
||||
case ip3DHoneycomb:
|
||||
case ipGyroid:
|
||||
case ipTpmsD:
|
||||
@@ -1097,6 +1105,7 @@ Polylines Layer::generate_sparse_infill_polylines_for_anchoring(FillAdaptive::Oc
|
||||
params.layer_height = layerm.layer()->height;
|
||||
params.lattice_angle_1 = surface_fill.params.lattice_angle_1;
|
||||
params.lattice_angle_2 = surface_fill.params.lattice_angle_2;
|
||||
params.infill_overhang_angle = surface_fill.params.infill_overhang_angle;
|
||||
|
||||
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
|
||||
@@ -40,6 +40,7 @@ Fill* Fill::new_from_type(const InfillPattern type)
|
||||
switch (type) {
|
||||
case ipConcentric: return new FillConcentric();
|
||||
case ipHoneycomb: return new FillHoneycomb();
|
||||
case ip2DHoneycomb: return new Fill2DHoneycomb();
|
||||
case ip3DHoneycomb: return new Fill3DHoneycomb();
|
||||
case ipGyroid: return new FillGyroid();
|
||||
case ipTpmsD: return new FillTpmsD();//from creality print
|
||||
|
||||
@@ -73,6 +73,9 @@ struct FillParams
|
||||
coordf_t lattice_angle_1 { 0.f };
|
||||
coordf_t lattice_angle_2 { 0.f };
|
||||
|
||||
// For 2D Honeycomb
|
||||
float infill_overhang_angle { 60 };
|
||||
|
||||
// BBS
|
||||
Flow flow;
|
||||
ExtrusionRole extrusion_role{ ExtrusionRole(0) };
|
||||
|
||||
@@ -3093,6 +3093,66 @@ Polylines FillQuarterCubic::fill_surface(const Surface* surface, const FillParam
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
Polylines Fill2DHoneycomb::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
{
|
||||
// the 2D honeycomb is generated based on a base pattern of an inverted Y with its junction at height zero
|
||||
// |
|
||||
// |
|
||||
// 0 --+--
|
||||
// / \
|
||||
// why inverted?
|
||||
// it makes determining some of the properties easier
|
||||
// and the two angled legs provide additional horizontal stiffness
|
||||
// the additional horizontal stiffness is not required close to the bed (unless you don't have any kind of bottom or flange)
|
||||
|
||||
using namespace boost::math::float_constants;
|
||||
|
||||
// lets begin calculating some base properties of the honeycomb pattern
|
||||
const float half_horizontal_period = .5f * (1*(2/3.f) + 2*(1/3.f)) * float(spacing) / params.density;
|
||||
const float vertical_period = 3 * half_horizontal_period / tanf(degree * float(params.infill_overhang_angle));
|
||||
|
||||
// we want to align the base pattern with its knot on height 0
|
||||
// therefore the double line part is 1/3 below and the single line is 2/3 above 0
|
||||
const float vertical_thirds_float = 3 * float(z) / vertical_period;
|
||||
const int vertical_thirds_int = vertical_thirds_float; // converstion to int does implicit floor wich is desired here
|
||||
const bool single_line = (vertical_thirds_int + 1) % 3;
|
||||
|
||||
// the base pattern needs to be horizontally shifted by half every odd pattern layer
|
||||
const bool odd_layer = ((vertical_thirds_int + 1) / 3) % 2;
|
||||
const float horizontal_offset = odd_layer ? half_horizontal_period : 0;
|
||||
|
||||
Polylines polylines_out;
|
||||
|
||||
if (single_line)
|
||||
{
|
||||
FillParams multiline_params = params;
|
||||
multiline_params.density *= 1 / (1*(2/3.) + 2*(1/3.));
|
||||
|
||||
if (!fill_surface_by_multilines(
|
||||
surface, multiline_params,
|
||||
{ { half_pi, horizontal_offset } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "Fill2DHoneycomb::fill_surface() failed to fill a region.";
|
||||
} else {
|
||||
FillParams multiline_params = params;
|
||||
multiline_params.density *= 2 / (1*(2/3.) + 2*(1/3.));
|
||||
|
||||
const float horizontal_position = (1 - (vertical_thirds_float - vertical_thirds_int)) * half_horizontal_period;
|
||||
|
||||
if (!fill_surface_by_multilines(
|
||||
surface, multiline_params,
|
||||
{ { half_pi, -horizontal_position + horizontal_offset }, { half_pi, horizontal_position + horizontal_offset } },
|
||||
polylines_out))
|
||||
BOOST_LOG_TRIVIAL(error) << "Fill2DHoneycomb::fill_surface() failed to fill a region.";
|
||||
}
|
||||
|
||||
if (this->layer_id % 2 == 1)
|
||||
for (int i = 0; i < polylines_out.size(); i++)
|
||||
std::reverse(polylines_out[i].begin(), polylines_out[i].end());
|
||||
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
Polylines FillSupportBase::fill_surface(const Surface *surface, const FillParams ¶ms)
|
||||
{
|
||||
assert(! params.full_infill());
|
||||
|
||||
@@ -132,6 +132,14 @@ protected:
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
};
|
||||
|
||||
class Fill2DHoneycomb : public FillAlignedRectilinear
|
||||
{
|
||||
public:
|
||||
Fill* clone() const override { return new Fill2DHoneycomb(*this); }
|
||||
~Fill2DHoneycomb() override = default;
|
||||
Polylines fill_surface(const Surface *surface, const FillParams ¶ms) override;
|
||||
};
|
||||
|
||||
|
||||
class FillSupportBase : public FillRectilinear
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user