New config value "gcode_resolution" replaces the hard coded RESOLUTION
value, which was set to 0.0125mm.
This commit is contained in:
parent
efaf4e47c1
commit
4158f9ec8e
@ -126,7 +126,7 @@ static ConstPrintObjectPtrs get_top_level_objects_with_brim(const Print &print,
|
||||
return top_level_objects_with_brim;
|
||||
}
|
||||
|
||||
static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_level_objects_with_brim)
|
||||
static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_level_objects_with_brim, const double scaled_resolution)
|
||||
{
|
||||
Polygons islands;
|
||||
for (const PrintObject *object : top_level_objects_with_brim) {
|
||||
@ -139,7 +139,7 @@ static Polygons top_level_outer_brim_islands(const ConstPrintObjectPtrs &top_lev
|
||||
for (const ExPolygon &ex_poly : get_print_object_bottom_layer_expolygons(*object)) {
|
||||
Polygons contour_offset = offset(ex_poly.contour, brim_separation, ClipperLib::jtSquare);
|
||||
for (Polygon &poly : contour_offset)
|
||||
poly.douglas_peucker(SCALED_RESOLUTION);
|
||||
poly.douglas_peucker(scaled_resolution);
|
||||
|
||||
polygons_append(islands_object, std::move(contour_offset));
|
||||
}
|
||||
@ -359,13 +359,14 @@ static void make_inner_brim(const Print &print,
|
||||
ExtrusionEntityCollection &brim)
|
||||
{
|
||||
assert(print.objects().size() == bottom_layers_expolygons.size());
|
||||
const auto scaled_resolution = scaled<double>(print.config().gcode_resolution.value);
|
||||
Flow flow = print.brim_flow();
|
||||
ExPolygons islands_ex = inner_brim_area(print, top_level_objects_with_brim, bottom_layers_expolygons, float(flow.scaled_spacing()));
|
||||
Polygons loops;
|
||||
islands_ex = offset_ex(islands_ex, -0.5f * float(flow.scaled_spacing()), ClipperLib::jtSquare);
|
||||
for (size_t i = 0; !islands_ex.empty(); ++i) {
|
||||
for (ExPolygon &poly_ex : islands_ex)
|
||||
poly_ex.douglas_peucker(SCALED_RESOLUTION);
|
||||
poly_ex.douglas_peucker(scaled_resolution);
|
||||
polygons_append(loops, to_polygons(islands_ex));
|
||||
islands_ex = offset_ex(islands_ex, -float(flow.scaled_spacing()), ClipperLib::jtSquare);
|
||||
}
|
||||
@ -380,10 +381,11 @@ static void make_inner_brim(const Print &print,
|
||||
// Collect islands_area to be merged into the final 1st layer convex hull.
|
||||
ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cancel, Polygons &islands_area)
|
||||
{
|
||||
const auto scaled_resolution = scaled<double>(print.config().gcode_resolution.value);
|
||||
Flow flow = print.brim_flow();
|
||||
std::vector<ExPolygons> bottom_layers_expolygons = get_print_bottom_layers_expolygons(print);
|
||||
ConstPrintObjectPtrs top_level_objects_with_brim = get_top_level_objects_with_brim(print, bottom_layers_expolygons);
|
||||
Polygons islands = top_level_outer_brim_islands(top_level_objects_with_brim);
|
||||
Polygons islands = top_level_outer_brim_islands(top_level_objects_with_brim, scaled_resolution);
|
||||
ExPolygons islands_area_ex = top_level_outer_brim_area(print, top_level_objects_with_brim, bottom_layers_expolygons, float(flow.scaled_spacing()));
|
||||
islands_area = to_polygons(islands_area_ex);
|
||||
|
||||
@ -393,7 +395,7 @@ ExtrusionEntityCollection make_brim(const Print &print, PrintTryCancel try_cance
|
||||
try_cancel();
|
||||
islands = expand(islands, float(flow.scaled_spacing()), ClipperLib::jtSquare);
|
||||
for (Polygon &poly : islands)
|
||||
poly.douglas_peucker(SCALED_RESOLUTION);
|
||||
poly.douglas_peucker(scaled_resolution);
|
||||
polygons_append(loops, shrink(islands, 0.5f * float(flow.scaled_spacing())));
|
||||
}
|
||||
loops = union_pt_chained_outside_in(loops);
|
||||
|
@ -329,7 +329,8 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
#endif /* SLIC3R_DEBUG_SLICE_PROCESSING */
|
||||
|
||||
std::vector<SurfaceFill> surface_fills = group_fills(*this);
|
||||
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||
const Slic3r::BoundingBox bbox = this->object()->bounding_box();
|
||||
const auto resolution = this->object()->print()->config().gcode_resolution.value;
|
||||
|
||||
#ifdef SLIC3R_DEBUG_SLICE_PROCESSING
|
||||
{
|
||||
@ -371,6 +372,7 @@ void Layer::make_fills(FillAdaptive::Octree* adaptive_fill_octree, FillAdaptive:
|
||||
params.dont_adjust = false; // surface_fill.params.dont_adjust;
|
||||
params.anchor_length = surface_fill.params.anchor_length;
|
||||
params.anchor_length_max = surface_fill.params.anchor_length_max;
|
||||
params.resolution = resolution;
|
||||
|
||||
for (ExPolygon &expoly : surface_fill.expolygons) {
|
||||
// Spacing is modified by the filler to indicate adjustments. Reset it for each expolygon.
|
||||
|
@ -44,6 +44,9 @@ struct FillParams
|
||||
float anchor_length { 1000.f };
|
||||
float anchor_length_max { 1000.f };
|
||||
|
||||
// G-code resolution.
|
||||
double resolution { 0.0125 };
|
||||
|
||||
// Don't adjust spacing to fill the space evenly.
|
||||
bool dont_adjust { true };
|
||||
|
||||
|
@ -31,7 +31,8 @@ void FillPlanePath::_fill_surface_single(
|
||||
coord_t(ceil(coordf_t(bounding_box.min.x()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.min.y()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max.x()) / distance_between_lines)),
|
||||
coord_t(ceil(coordf_t(bounding_box.max.y()) / distance_between_lines)));
|
||||
coord_t(ceil(coordf_t(bounding_box.max.y()) / distance_between_lines)),
|
||||
params.resolution);
|
||||
|
||||
if (pts.size() >= 2) {
|
||||
// Convert points to a polyline, upscale.
|
||||
@ -58,7 +59,7 @@ void FillPlanePath::_fill_surface_single(
|
||||
}
|
||||
|
||||
// Follow an Archimedean spiral, in polar coordinates: r=a+b\theta
|
||||
Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
|
||||
Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double resolution)
|
||||
{
|
||||
// Radius to achieve.
|
||||
coordf_t rmax = std::sqrt(coordf_t(max_x)*coordf_t(max_x)+coordf_t(max_y)*coordf_t(max_y)) * std::sqrt(2.) + 1.5;
|
||||
@ -72,8 +73,8 @@ Pointfs FillArchimedeanChords::_generate(coord_t min_x, coord_t min_y, coord_t m
|
||||
out.emplace_back(0, 0);
|
||||
out.emplace_back(1, 0);
|
||||
while (r < rmax) {
|
||||
// Discretization angle to achieve a discretization error lower than RESOLUTION.
|
||||
theta += 2. * acos(1. - RESOLUTION / r);
|
||||
// Discretization angle to achieve a discretization error lower than resolution.
|
||||
theta += 2. * acos(1. - resolution / r);
|
||||
r = a + b * theta;
|
||||
out.emplace_back(r * cos(theta), r * sin(theta));
|
||||
}
|
||||
@ -125,7 +126,7 @@ static inline Point hilbert_n_to_xy(const size_t n)
|
||||
return Point(x, y);
|
||||
}
|
||||
|
||||
Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
|
||||
Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double /* resolution */)
|
||||
{
|
||||
// Minimum power of two square to fit the domain.
|
||||
size_t sz = 2;
|
||||
@ -148,7 +149,7 @@ Pointfs FillHilbertCurve::_generate(coord_t min_x, coord_t min_y, coord_t max_x,
|
||||
return line;
|
||||
}
|
||||
|
||||
Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y)
|
||||
Pointfs FillOctagramSpiral::_generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double /* resolution */)
|
||||
{
|
||||
// Radius to achieve.
|
||||
coordf_t rmax = std::sqrt(coordf_t(max_x)*coordf_t(max_x)+coordf_t(max_y)*coordf_t(max_y)) * std::sqrt(2.) + 1.5;
|
||||
|
@ -28,7 +28,7 @@ protected:
|
||||
|
||||
float _layer_angle(size_t idx) const override { return 0.f; }
|
||||
virtual bool _centered() const = 0;
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) = 0;
|
||||
virtual Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double resolution) = 0;
|
||||
};
|
||||
|
||||
class FillArchimedeanChords : public FillPlanePath
|
||||
@ -39,7 +39,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool _centered() const override { return true; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) override;
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double resolution) override;
|
||||
};
|
||||
|
||||
class FillHilbertCurve : public FillPlanePath
|
||||
@ -50,7 +50,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool _centered() const override { return false; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) override;
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double resolution) override;
|
||||
};
|
||||
|
||||
class FillOctagramSpiral : public FillPlanePath
|
||||
@ -61,7 +61,7 @@ public:
|
||||
|
||||
protected:
|
||||
bool _centered() const override { return true; }
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y) override;
|
||||
Pointfs _generate(coord_t min_x, coord_t min_y, coord_t max_x, coord_t max_y, const double resolution) override;
|
||||
};
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -2414,6 +2414,7 @@ void GCode::apply_print_config(const PrintConfig &print_config)
|
||||
{
|
||||
m_writer.apply_print_config(print_config);
|
||||
m_config.apply(print_config);
|
||||
m_scaled_resolution = scaled<double>(print_config.gcode_resolution.value);
|
||||
}
|
||||
|
||||
void GCode::append_full_config(const Print &print, std::string &str)
|
||||
@ -2565,7 +2566,7 @@ std::string GCode::extrude_loop(ExtrusionLoop loop, std::string description, dou
|
||||
for (ExtrusionPaths::iterator path = paths.begin(); path != paths.end(); ++path) {
|
||||
// description += ExtrusionLoop::role_to_string(loop.loop_role());
|
||||
// description += ExtrusionEntity::role_to_string(path->role);
|
||||
path->simplify(SCALED_RESOLUTION);
|
||||
path->simplify(m_scaled_resolution);
|
||||
gcode += this->_extrude(*path, description, speed);
|
||||
}
|
||||
|
||||
@ -2619,7 +2620,7 @@ std::string GCode::extrude_multi_path(ExtrusionMultiPath multipath, std::string
|
||||
for (ExtrusionPath path : multipath.paths) {
|
||||
// description += ExtrusionLoop::role_to_string(loop.loop_role());
|
||||
// description += ExtrusionEntity::role_to_string(path->role);
|
||||
path.simplify(SCALED_RESOLUTION);
|
||||
path.simplify(m_scaled_resolution);
|
||||
gcode += this->_extrude(path, description, speed);
|
||||
}
|
||||
if (m_wipe.enable) {
|
||||
@ -2647,7 +2648,7 @@ std::string GCode::extrude_entity(const ExtrusionEntity &entity, std::string des
|
||||
std::string GCode::extrude_path(ExtrusionPath path, std::string description, double speed)
|
||||
{
|
||||
// description += ExtrusionEntity::role_to_string(path.role());
|
||||
path.simplify(SCALED_RESOLUTION);
|
||||
path.simplify(m_scaled_resolution);
|
||||
std::string gcode = this->_extrude(path, description, speed);
|
||||
if (m_wipe.enable) {
|
||||
m_wipe.path = std::move(path.polyline);
|
||||
|
@ -345,6 +345,8 @@ private:
|
||||
methods. */
|
||||
Vec2d m_origin;
|
||||
FullPrintConfig m_config;
|
||||
// scaled G-code resolution
|
||||
double m_scaled_resolution;
|
||||
GCodeWriter m_writer;
|
||||
PlaceholderParser m_placeholder_parser;
|
||||
// For random number generator etc.
|
||||
|
@ -322,7 +322,7 @@ void PerimeterGenerator::process()
|
||||
for (const Surface &surface : this->slices->surfaces) {
|
||||
// detect how many perimeters must be generated for this island
|
||||
int loop_number = this->config->perimeters + surface.extra_perimeters - 1; // 0-indexed loops
|
||||
ExPolygons last = union_ex(surface.expolygon.simplify_p(SCALED_RESOLUTION));
|
||||
ExPolygons last = union_ex(surface.expolygon.simplify_p(m_scaled_resolution));
|
||||
ExPolygons gaps;
|
||||
if (loop_number >= 0) {
|
||||
// In case no perimeters are to be generated, loop_number will equal to -1.
|
||||
@ -533,7 +533,7 @@ void PerimeterGenerator::process()
|
||||
// simplify infill contours according to resolution
|
||||
Polygons pp;
|
||||
for (ExPolygon &ex : last)
|
||||
ex.simplify_p(SCALED_RESOLUTION, &pp);
|
||||
ex.simplify_p(m_scaled_resolution, &pp);
|
||||
// collapse too narrow infill areas
|
||||
coord_t min_perimeter_infill_spacing = coord_t(solid_infill_spacing * (1. - INSET_OVERLAP_TOLERANCE));
|
||||
// append infill areas to fill_surfaces
|
||||
|
@ -50,6 +50,7 @@ public:
|
||||
overhang_flow(flow), solid_infill_flow(flow),
|
||||
config(config), object_config(object_config), print_config(print_config),
|
||||
m_spiral_vase(spiral_vase),
|
||||
m_scaled_resolution(scaled<double>(print_config->gcode_resolution.value)),
|
||||
loops(loops), gap_fill(gap_fill), fill_surfaces(fill_surfaces),
|
||||
m_ext_mm3_per_mm(-1), m_mm3_per_mm(-1), m_mm3_per_mm_overhang(-1)
|
||||
{}
|
||||
@ -63,6 +64,7 @@ public:
|
||||
|
||||
private:
|
||||
bool m_spiral_vase;
|
||||
double m_scaled_resolution;
|
||||
double m_ext_mm3_per_mm;
|
||||
double m_mm3_per_mm;
|
||||
double m_mm3_per_mm_overhang;
|
||||
|
@ -444,7 +444,7 @@ static std::vector<std::string> s_Preset_print_options {
|
||||
"ooze_prevention", "standby_temperature_delta", "interface_shells", "extrusion_width", "first_layer_extrusion_width",
|
||||
"perimeter_extrusion_width", "external_perimeter_extrusion_width", "infill_extrusion_width", "solid_infill_extrusion_width",
|
||||
"top_infill_extrusion_width", "support_material_extrusion_width", "infill_overlap", "infill_anchor", "infill_anchor_max", "bridge_flow_ratio", "clip_multipart_objects",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"elefant_foot_compensation", "xy_size_compensation", "threads", "resolution", "gcode_resolution", "wipe_tower", "wipe_tower_x", "wipe_tower_y",
|
||||
"wipe_tower_width", "wipe_tower_rotation_angle", "wipe_tower_brim_width", "wipe_tower_bridging", "single_extruder_multi_material_priming", "mmu_segmented_region_max_width",
|
||||
"wipe_tower_no_sparse_layers", "compatible_printers", "compatible_printers_condition", "inherits"
|
||||
};
|
||||
|
@ -214,7 +214,8 @@ bool Print::invalidate_state_by_config_options(const ConfigOptionResolver & /* n
|
||||
} else if (
|
||||
opt_key == "first_layer_extrusion_width"
|
||||
|| opt_key == "min_layer_height"
|
||||
|| opt_key == "max_layer_height") {
|
||||
|| opt_key == "max_layer_height"
|
||||
|| opt_key == "gcode_resolution") {
|
||||
osteps.emplace_back(posPerimeters);
|
||||
osteps.emplace_back(posInfill);
|
||||
osteps.emplace_back(posSupportMaterial);
|
||||
|
@ -2072,7 +2072,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->set_default_value(new ConfigOptionInt(0));
|
||||
|
||||
def = this->add("resolution", coFloat);
|
||||
def->label = L("Resolution");
|
||||
def->label = L("Slice resolution");
|
||||
def->tooltip = L("Minimum detail resolution, used to simplify the input file for speeding up "
|
||||
"the slicing job and reducing memory usage. High-resolution models often carry "
|
||||
"more detail than printers can render. Set to zero to disable any simplification "
|
||||
@ -2082,6 +2082,18 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0));
|
||||
|
||||
def = this->add("gcode_resolution", coFloat);
|
||||
def->label = L("G-code resolution");
|
||||
def->tooltip = L("Maximum deviation of exported G-code paths from their full resolution counterparts. "
|
||||
"Very high resolution G-code requires huge amount of RAM to slice and preview, "
|
||||
"also a 3D printer may stutter not being able to process a high resolution G-code in a timely manner. "
|
||||
"On the other hand, a low resolution G-code will produce a low poly effect and because "
|
||||
"the G-code reduction is performed at each layer independently, visible artifacts may be produced.");
|
||||
def->sidetext = L("mm");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloat(0.0125));
|
||||
|
||||
def = this->add("retract_before_travel", coFloats);
|
||||
def->label = L("Minimum travel after retraction");
|
||||
def->tooltip = L("Retraction is not triggered when travel moves are shorter than this length.");
|
||||
@ -3940,6 +3952,10 @@ void DynamicPrintConfig::normalize_fdm()
|
||||
this->opt<ConfigOptionPercent>("fill_density", true)->value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto *opt_gcode_resolution = this->opt<ConfigOptionFloat>("gcode_resolution", false); opt_gcode_resolution)
|
||||
// Resolution will be above 1um.
|
||||
opt_gcode_resolution->value = std::max(opt_gcode_resolution->value, 0.001);
|
||||
}
|
||||
|
||||
void handle_legacy_sla(DynamicPrintConfig &config)
|
||||
|
@ -734,6 +734,7 @@ PRINT_CONFIG_CLASS_DERIVED_DEFINE(
|
||||
((ConfigOptionString, printer_model))
|
||||
((ConfigOptionString, printer_notes))
|
||||
((ConfigOptionFloat, resolution))
|
||||
((ConfigOptionFloat, gcode_resolution))
|
||||
((ConfigOptionFloats, retract_before_travel))
|
||||
((ConfigOptionBools, retract_layer_change))
|
||||
((ConfigOptionFloat, skirt_distance))
|
||||
|
@ -47,9 +47,6 @@ static constexpr double EPSILON = 1e-4;
|
||||
// int32_t fits an interval of (-2147.48mm, +2147.48mm)
|
||||
// with int64_t we don't have to worry anymore about the size of the int.
|
||||
static constexpr double SCALING_FACTOR = 0.000001;
|
||||
// RESOLUTION, SCALED_RESOLUTION: Used as an error threshold for a Douglas-Peucker polyline simplification algorithm.
|
||||
static constexpr double RESOLUTION = 0.0125;
|
||||
#define SCALED_RESOLUTION (RESOLUTION / SCALING_FACTOR)
|
||||
static constexpr double PI = 3.141592653589793238;
|
||||
// When extruding a closed loop, the loop is interrupted and shortened a bit to reduce the seam.
|
||||
static constexpr double LOOP_CLIPPING_LENGTH_OVER_NOZZLE_DIAMETER = 0.15;
|
||||
|
@ -1650,6 +1650,7 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("slice_closing_radius");
|
||||
optgroup->append_single_option_line("slicing_mode");
|
||||
optgroup->append_single_option_line("resolution");
|
||||
optgroup->append_single_option_line("gcode_resolution");
|
||||
optgroup->append_single_option_line("xy_size_compensation");
|
||||
optgroup->append_single_option_line("elefant_foot_compensation", "elephant-foot-compensation_114487");
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user