mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-08-14 20:05:56 +08:00
add parameters: fill_top_flow_ratio & fill_smooth_width
bugfix flow inaccuracies in FillSmooth. TODO: do something about surface too small to be printed, particularly when 'only one perimeter top' -> don't extract them or use gapfill
This commit is contained in:
parent
b05618c883
commit
89b2e62381
@ -178,8 +178,9 @@ printer_model = Custom_1.75mm
|
||||
avoid_crossing_perimeters = 0
|
||||
bridge_acceleration = 1000
|
||||
bridge_angle = 0
|
||||
bridge_flow_ratio = 0.8
|
||||
over_bridge_flow_ratio = 1.05
|
||||
bridge_flow_ratio = 80%
|
||||
over_bridge_flow_ratio = 105%
|
||||
fill_top_flow_ratio = 100%
|
||||
bridge_speed = 20
|
||||
brim_width = 0
|
||||
clip_multipart_objects = 1
|
||||
@ -291,148 +292,60 @@ perimeters = 6
|
||||
infill_overlap = 40%
|
||||
first_layer_height = 0.1
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.15
|
||||
extrusion_width = 0.16
|
||||
external_perimeter_extrusion_width = 0.16
|
||||
first_layer_extrusion_width = 0.2
|
||||
infill_extrusion_width = 0.17
|
||||
perimeter_extrusion_width = 0.17
|
||||
solid_infill_extrusion_width = 0.17
|
||||
top_infill_extrusion_width = 0.16
|
||||
support_material_extrusion_width = 0.17
|
||||
|
||||
[print:*0.2nozzle*]
|
||||
perimeters = 5
|
||||
infill_overlap = 35%
|
||||
first_layer_height = 0.14
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.2
|
||||
extrusion_width = 0.21
|
||||
external_perimeter_extrusion_width = 0.22
|
||||
first_layer_extrusion_width = 0.3
|
||||
infill_extrusion_width = 0.22
|
||||
perimeter_extrusion_width = 0.22
|
||||
solid_infill_extrusion_width = 0.22
|
||||
top_infill_extrusion_width = 0.21
|
||||
support_material_extrusion_width = 0.22
|
||||
|
||||
[print:*0.25nozzle*]
|
||||
perimeters = 4
|
||||
infill_overlap = 30%
|
||||
first_layer_height = 0.17
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.25
|
||||
extrusion_width = 0.26
|
||||
external_perimeter_extrusion_width = 0.26
|
||||
first_layer_extrusion_width = 0.35
|
||||
infill_extrusion_width = 0.27
|
||||
perimeter_extrusion_width = 0.27
|
||||
solid_infill_extrusion_width = 0.27
|
||||
top_infill_extrusion_width = 0.26
|
||||
support_material_extrusion_width = 0.27
|
||||
|
||||
[print:*0.3nozzle*]
|
||||
perimeters = 4
|
||||
infill_overlap = 25%
|
||||
first_layer_height = 0.2
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.3
|
||||
extrusion_width = 0.32
|
||||
external_perimeter_extrusion_width = 0.32
|
||||
first_layer_extrusion_width = 0.45
|
||||
infill_extrusion_width = 0.33
|
||||
perimeter_extrusion_width = 0.33
|
||||
solid_infill_extrusion_width = 0.33
|
||||
top_infill_extrusion_width = 0.32
|
||||
support_material_extrusion_width = 0.33
|
||||
|
||||
[print:*0.35nozzle*]
|
||||
perimeters = 3
|
||||
infill_overlap = 25%
|
||||
first_layer_height = 0.2
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.35
|
||||
extrusion_width = 0.37
|
||||
external_perimeter_extrusion_width = 0.37
|
||||
first_layer_extrusion_width = 0.5
|
||||
infill_extrusion_width = 0.39
|
||||
perimeter_extrusion_width = 0.39
|
||||
solid_infill_extrusion_width = 0.39
|
||||
top_infill_extrusion_width = 0.37
|
||||
support_material_extrusion_width = 0.39
|
||||
|
||||
[print:*0.4nozzle*]
|
||||
perimeters = 3
|
||||
infill_overlap = 25%
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.4
|
||||
extrusion_width = 0.42
|
||||
external_perimeter_extrusion_width = 0.42
|
||||
first_layer_extrusion_width = 0.6
|
||||
infill_extrusion_width = 0.44
|
||||
perimeter_extrusion_width = 0.44
|
||||
solid_infill_extrusion_width = 0.44
|
||||
top_infill_extrusion_width = 0.42
|
||||
support_material_extrusion_width = 0.44
|
||||
|
||||
[print:*0.5nozzle*]
|
||||
perimeters = 3
|
||||
infill_overlap = 20%
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.5
|
||||
extrusion_width = 0.52
|
||||
external_perimeter_extrusion_width = 0.52
|
||||
first_layer_extrusion_width = 0.7
|
||||
infill_extrusion_width = 0.55
|
||||
perimeter_extrusion_width = 0.55
|
||||
solid_infill_extrusion_width = 0.55
|
||||
top_infill_extrusion_width = 0.52
|
||||
support_material_extrusion_width = 0.52
|
||||
|
||||
[print:*0.6nozzle*]
|
||||
perimeters = 2
|
||||
infill_overlap = 15%
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.6
|
||||
extrusion_width = 0.63
|
||||
external_perimeter_extrusion_width = 0.63
|
||||
first_layer_extrusion_width = 0.8
|
||||
infill_extrusion_width = 0.66
|
||||
perimeter_extrusion_width = 0.66
|
||||
solid_infill_extrusion_width = 0.66
|
||||
top_infill_extrusion_width = 0.63
|
||||
support_material_extrusion_width = 0.66
|
||||
|
||||
[print:*0.8nozzle*]
|
||||
perimeters = 2
|
||||
infill_overlap = 15%
|
||||
compatible_printers_condition = nozzle_diameter[0]==0.8
|
||||
extrusion_width = 0.84
|
||||
external_perimeter_extrusion_width = 0.84
|
||||
first_layer_extrusion_width = 1
|
||||
infill_extrusion_width = 0.88
|
||||
perimeter_extrusion_width = 0.88
|
||||
solid_infill_extrusion_width = 0.88
|
||||
top_infill_extrusion_width = 0.84
|
||||
support_material_extrusion_width = 0.88
|
||||
|
||||
[print:*1.0nozzle*]
|
||||
perimeters = 1
|
||||
infill_overlap = 10%
|
||||
compatible_printers_condition = nozzle_diameter[0]==1
|
||||
extrusion_width = 1.05
|
||||
external_perimeter_extrusion_width = 1.05
|
||||
first_layer_extrusion_width = 1.2
|
||||
infill_extrusion_width = 1.1
|
||||
perimeter_extrusion_width = 1.1
|
||||
solid_infill_extrusion_width = 1.1
|
||||
top_infill_extrusion_width = 1.05
|
||||
support_material_extrusion_width = 1.1
|
||||
|
||||
[print:*1.2nozzle*]
|
||||
perimeters = 1
|
||||
infill_overlap = 10%
|
||||
compatible_printers_condition = nozzle_diameter[0]==1.2
|
||||
extrusion_width = 1.25
|
||||
external_perimeter_extrusion_width = 1.25
|
||||
first_layer_extrusion_width = 1.4
|
||||
infill_extrusion_width = 1.3
|
||||
perimeter_extrusion_width = 1.3
|
||||
solid_infill_extrusion_width = 1.3
|
||||
top_infill_extrusion_width = 1.25
|
||||
support_material_extrusion_width = 1.3
|
||||
|
||||
[print:*0.08mm*]
|
||||
inherits = *common*
|
||||
|
@ -94,8 +94,9 @@ family = SL1
|
||||
avoid_crossing_perimeters = 0
|
||||
bridge_acceleration = 1000
|
||||
bridge_angle = 0
|
||||
bridge_flow_ratio = 0.8
|
||||
over_bridge_flow_ratio = 1.2
|
||||
bridge_flow_ratio = 80%
|
||||
over_bridge_flow_ratio = 120%
|
||||
fill_top_flow_ratio = 120%
|
||||
bridge_speed = 20
|
||||
brim_width = 0
|
||||
clip_multipart_objects = 1
|
||||
|
@ -1734,7 +1734,11 @@ public:
|
||||
int opt_int(const t_config_option_key &opt_key, unsigned int idx) const { return dynamic_cast<const ConfigOptionInts*>(this->option(opt_key))->get_at(idx); }
|
||||
|
||||
template<typename ENUM>
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const { return (ENUM)dynamic_cast<const ConfigOptionEnumGeneric*>(this->option(opt_key))->value; }
|
||||
ENUM opt_enum(const t_config_option_key &opt_key) const {
|
||||
auto v1 = this->option<ConfigOptionEnumGeneric>(opt_key);
|
||||
auto v2 = this->option<ConfigOptionEnum<ENUM>>(opt_key);
|
||||
return v1==nullptr? v2->value : (ENUM)v1->value;
|
||||
}
|
||||
|
||||
bool opt_bool(const t_config_option_key &opt_key) const { return this->option<ConfigOptionBool>(opt_key)->value != 0; }
|
||||
bool opt_bool(const t_config_option_key &opt_key, unsigned int idx) const { return this->option<ConfigOptionBools>(opt_key)->get_at(idx) != 0; }
|
||||
|
@ -315,13 +315,18 @@ void make_fill(LayerRegion &layerm, ExtrusionEntityCollection &out)
|
||||
flow = Flow::new_from_spacing(f->spacing, flow.nozzle_diameter, (float)h, is_bridge || f->use_bridge_flow());
|
||||
}
|
||||
|
||||
//adjust flow (to over-extrude when needed)
|
||||
float flow_percent = 1;
|
||||
if (surface.has_pos_top()) flow_percent *= layerm.region()->config().fill_top_flow_ratio.get_abs_value(1);
|
||||
params.flow_mult = flow_percent;
|
||||
|
||||
//adjust spacing (to over-extrude when needed)
|
||||
if (surface.has_mod_overBridge()){
|
||||
params.density = layerm.region()->config().over_bridge_flow_ratio;
|
||||
//params.flow_mult = layerm.region()->config().over_bridge_flow_ratio;
|
||||
params.density = layerm.region()->config().over_bridge_flow_ratio.get_abs_value(1);
|
||||
}
|
||||
|
||||
|
||||
params.flow = &flow;
|
||||
params.config = &layerm.region()->config();
|
||||
f->fill_surface_extrusion(&surface, params, out.entities);
|
||||
}
|
||||
|
||||
|
@ -214,7 +214,7 @@ void Fill::fill_surface_extrusion(const Surface *surface, const FillParams ¶
|
||||
eec->entities, std::move(polylines),
|
||||
good_role,
|
||||
params.flow->mm3_per_mm() * params.flow_mult * multFlow,
|
||||
params.flow->width * params.flow_mult * multFlow,
|
||||
(float)(params.flow->width * params.flow_mult * multFlow),
|
||||
(float)params.flow->height);
|
||||
|
||||
}
|
||||
@ -277,9 +277,10 @@ void cut_polygon(Polyline &poly, size_t idx_1, Point p1, Point p2) {
|
||||
/// it use equally_spaced_points with width/2 precision, so don't worry with pts_to_check number of points.
|
||||
/// it use the given polylines_blocker points, be sure to put enough of them to be reliable.
|
||||
/// complexity : N(pts_to_check.equally_spaced_points(width / 2)) x N(polylines_blocker.points)
|
||||
bool collision(const Points &pts_to_check, const Polylines &polylines_blocker, const coordf_t width) {
|
||||
bool collision(const Points &pts_to_check, const Polylines &polylines_blocker, const coord_t width) {
|
||||
//check if it's not too close to a polyline
|
||||
coordf_t min_dist_square = width * width * 0.9 - SCALED_EPSILON;
|
||||
//convert to double to allow ² operation
|
||||
double min_dist_square = (double)width * (double)width * 0.9 - SCALED_EPSILON;
|
||||
Polyline better_polylines(pts_to_check);
|
||||
Points better_pts = better_polylines.equally_spaced_points(width / 2);
|
||||
for (const Point &p : better_pts) {
|
||||
@ -298,6 +299,8 @@ bool collision(const Points &pts_to_check, const Polylines &polylines_blocker, c
|
||||
/// width if the width of the extrusion
|
||||
/// polylines_blockers are the array of polylines to check if the path isn't blocked by something.
|
||||
/// complexity: N(polylines.points) + a collision check after that if we finded a path: N(2(p2-p1)/width) x N(polylines_blocker.points)
|
||||
/// @param width is scaled
|
||||
/// @param max_size is scaled
|
||||
Points getFrontier(Polylines &polylines, const Point& p1, const Point& p2, const coord_t width, const Polylines &polylines_blockers, coord_t max_size = -1) {
|
||||
for (size_t idx_poly = 0; idx_poly < polylines.size(); ++idx_poly) {
|
||||
Polyline &poly = polylines[idx_poly];
|
||||
@ -486,8 +489,8 @@ void Fill::connect_infill(const Polylines &infill_ordered, const ExPolygon &boun
|
||||
for (const Polyline &polyline : infill_ordered) {
|
||||
if (polyline.length() > 2.01 * clip_size) {
|
||||
polylines_blocker.push_back(polyline);
|
||||
polylines_blocker.back().clip_end(clip_size);
|
||||
polylines_blocker.back().clip_start(clip_size);
|
||||
polylines_blocker.back().clip_end((double)clip_size);
|
||||
polylines_blocker.back().clip_start((double)clip_size);
|
||||
}
|
||||
}
|
||||
|
||||
@ -503,7 +506,7 @@ void Fill::connect_infill(const Polylines &infill_ordered, const ExPolygon &boun
|
||||
const Point &last_point = pts_end.back();
|
||||
const Point &first_point = polyline.points.front();
|
||||
if (last_point.distance_to(first_point) < scale_(this->spacing) * 10) {
|
||||
Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, scale_(this->spacing), polylines_blocker, (coord_t)scale_(ideal_length) * 2);
|
||||
Points pts_frontier = getFrontier(polylines_frontier, last_point, first_point, scale_(this->spacing), polylines_blocker, scale_(ideal_length) * 2);
|
||||
if (!pts_frontier.empty()) {
|
||||
// The lines can be connected.
|
||||
pts_end.insert(pts_end.end(), pts_frontier.begin(), pts_frontier.end());
|
||||
|
@ -30,6 +30,7 @@ struct FillParams
|
||||
fill_exactly = false;
|
||||
role = erNone;
|
||||
flow = NULL;
|
||||
config = NULL;
|
||||
}
|
||||
|
||||
bool full_infill() const { return density > 0.9999f && density < 1.0001f; }
|
||||
@ -59,6 +60,9 @@ struct FillParams
|
||||
|
||||
//flow to use
|
||||
Flow const *flow;
|
||||
|
||||
//full configuration for the region, to avoid copying every bit that is needed. Use this for process-specific parameters.
|
||||
PrintRegionConfig const *config;
|
||||
};
|
||||
static_assert(IsTriviallyCopyable<FillParams>::value, "FillParams class is not POD (and it should be - see constructor).");
|
||||
|
||||
@ -135,6 +139,8 @@ protected:
|
||||
|
||||
void connect_infill(const Polylines &infill_ordered, const ExPolygon &boundary, Polylines &polylines_out, const FillParams ¶ms);
|
||||
|
||||
void do_gap_fill(const ExPolygons &gapfill_areas, const FillParams ¶ms, ExtrusionEntitiesPtr &coll_out);
|
||||
|
||||
ExtrusionRole getRoleFromSurfaceType(const FillParams ¶ms, const Surface *surface){
|
||||
if (params.role == erNone || params.role == erCustom) {
|
||||
return params.flow->bridge ?
|
||||
|
@ -1767,22 +1767,39 @@ FillRectilinearSawtooth::fill_surface_extrusion(const Surface *surface, const Fi
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) {
|
||||
ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
|
||||
coll_nosort->no_sort = true; //can be sorted inside the pass
|
||||
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
|
||||
void FillRectilinear2WGapFill::split_polygon_gap_fill(const Surface &surface, const FillParams ¶ms, ExPolygons &rectilinear, ExPolygons &gapfill) {
|
||||
|
||||
// remove areas for gapfill
|
||||
// factor=0.5 : remove area smaller than a spacing. factor=1 : max spacing for the gapfill (but not the width)
|
||||
//choose between 2 to avoid dotted line effect.
|
||||
float factor1 = 0.99f;
|
||||
float factor2 = 0.7f;
|
||||
ExPolygons rectilinear_areas1 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor1, params.flow->scaled_spacing() * factor1);
|
||||
ExPolygons rectilinear_areas2 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor2, params.flow->scaled_spacing() * factor2);
|
||||
std::cout << "FillRectilinear2WGapFill use " << (rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? "1" : "2") << "\n";
|
||||
ExPolygons &rectilinear_areas = rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? rectilinear_areas1 : rectilinear_areas2;
|
||||
ExPolygons gapfill_areas = diff_ex(ExPolygons{ surface->expolygon }, rectilinear_areas);
|
||||
ExPolygons rectilinear_areas1 = offset2_ex(ExPolygons{ surface.expolygon }, -params.flow->scaled_spacing() * factor1, params.flow->scaled_spacing() * factor1);
|
||||
ExPolygons rectilinear_areas2 = offset2_ex(ExPolygons{ surface.expolygon }, -params.flow->scaled_spacing() * factor2, params.flow->scaled_spacing() * factor2);
|
||||
//choose the best one
|
||||
rectilinear = rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 || rectilinear_areas2.empty() ? rectilinear_areas1 : rectilinear_areas2;
|
||||
//get gapfill
|
||||
gapfill = diff_ex(ExPolygons{ surface.expolygon }, rectilinear);
|
||||
}
|
||||
|
||||
void
|
||||
FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) {
|
||||
ExtrusionEntityCollection *coll_nosort = new ExtrusionEntityCollection();
|
||||
coll_nosort->no_sort = true; //can be sorted inside the pass
|
||||
ExtrusionRole good_role = getRoleFromSurfaceType(params, surface);
|
||||
|
||||
//// remove areas for gapfill
|
||||
//// factor=0.5 : remove area smaller than a spacing. factor=1 : max spacing for the gapfill (but not the width)
|
||||
////choose between 2 to avoid dotted line effect.
|
||||
//float factor1 = 0.99f;
|
||||
//float factor2 = 0.7f;
|
||||
//ExPolygons rectilinear_areas1 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor1, params.flow->scaled_spacing() * factor1);
|
||||
//ExPolygons rectilinear_areas2 = offset2_ex(ExPolygons{ surface->expolygon }, -params.flow->scaled_spacing() * factor2, params.flow->scaled_spacing() * factor2);
|
||||
//std::cout << "FillRectilinear2WGapFill use " << (rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? "1" : "2") << "\n";
|
||||
//ExPolygons &rectilinear_areas = rectilinear_areas1.size() <= rectilinear_areas2.size() + 1 ? rectilinear_areas1 : rectilinear_areas2;
|
||||
//ExPolygons gapfill_areas = diff_ex(ExPolygons{ surface->expolygon }, rectilinear_areas);
|
||||
ExPolygons rectilinear_areas, gapfill_areas;
|
||||
split_polygon_gap_fill(*surface, params, rectilinear_areas, gapfill_areas);
|
||||
double rec_area = 0;
|
||||
for (ExPolygon &p : rectilinear_areas)rec_area += p.area();
|
||||
double gf_area = 0;
|
||||
@ -1793,7 +1810,7 @@ FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const F
|
||||
Polylines polylines_rectilinear;
|
||||
Surface rectilinear_surface{ *surface };
|
||||
for (const ExPolygon &rectilinear_area : rectilinear_areas) {
|
||||
rectilinear_surface.expolygon = rectilinear_area;
|
||||
rectilinear_surface.expolygon = rectilinear_area, 0 - 0.5 * params.flow->scaled_spacing();
|
||||
if (!fill_surface_by_lines(&rectilinear_surface, params, 0.f, 0.f, polylines_rectilinear)) {
|
||||
printf("FillRectilinear2::fill_surface() failed to fill a region.\n");
|
||||
}
|
||||
@ -1855,48 +1872,9 @@ FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const F
|
||||
|
||||
//gapfill
|
||||
if (gapfill_areas.size() > 0) {
|
||||
ThickPolylines polylines_gapfill;
|
||||
double min = 0.4 * scale_(params.flow->nozzle_diameter) * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
double max = 2. * params.flow->scaled_width();
|
||||
// collapse
|
||||
//be sure we don't gapfill where the perimeters are already touching each other (negative spacing).
|
||||
min = std::max(min, double(Flow::new_from_spacing(EPSILON, params.flow->nozzle_diameter , params.flow->height, false).scaled_width()));
|
||||
//ExPolygons gapfill_areas_collapsed = diff_ex(
|
||||
// offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2)),
|
||||
// offset2_ex(gapfill_areas, double(-max / 2), double(+max / 2)),
|
||||
// true);
|
||||
ExPolygons gapfill_areas_collapsed = offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2));
|
||||
for (const ExPolygon &ex : gapfill_areas_collapsed) {
|
||||
//remove too small gaps that are too hard to fill.
|
||||
//ie one that are smaller than an extrusion with width of min and a length of max.
|
||||
if (ex.area() > scale_(params.flow->nozzle_diameter)*scale_(params.flow->nozzle_diameter) * 2) {
|
||||
MedialAxis{ ex, params.flow->scaled_width() * 2, params.flow->scaled_width() / 5, coord_t(params.flow->height) }.build(polylines_gapfill);
|
||||
}
|
||||
}
|
||||
if (!polylines_gapfill.empty() && good_role != erBridgeInfill) {
|
||||
//test
|
||||
for (ThickPolyline poly : polylines_gapfill) {
|
||||
for (coordf_t width : poly.width) {
|
||||
if (width > params.flow->scaled_width() * 2.2) {
|
||||
std::cout << "ERRROR!!!! recti gapfill width = " << unscaled(width) << " > max_width = " << (params.flow->width * 2) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, *params.flow);
|
||||
//set role if needed
|
||||
if (good_role != erSolidInfill) {
|
||||
ExtrusionSetRole set_good_role(good_role);
|
||||
gap_fill.visit(set_good_role);
|
||||
}
|
||||
//move them into the collection
|
||||
if (!gap_fill.entities.empty()) {
|
||||
ExtrusionEntityCollection *coll_gapfill = new ExtrusionEntityCollection();
|
||||
coll_gapfill->no_sort = this->no_sort();
|
||||
coll_gapfill->append(std::move(gap_fill.entities));
|
||||
coll_nosort->entities.push_back(coll_gapfill);
|
||||
}
|
||||
}
|
||||
FillParams params2{ params };
|
||||
params2.role = good_role;
|
||||
do_gap_fill(gapfill_areas, params2, coll_nosort->entities);
|
||||
}
|
||||
|
||||
// === end ===
|
||||
@ -1908,6 +1886,55 @@ FillRectilinear2WGapFill::fill_surface_extrusion(const Surface *surface, const F
|
||||
|
||||
}
|
||||
|
||||
void
|
||||
Fill::do_gap_fill(const ExPolygons &gapfill_areas, const FillParams ¶ms, ExtrusionEntitiesPtr &coll_out) {
|
||||
|
||||
ThickPolylines polylines_gapfill;
|
||||
double min = 0.4 * scale_(params.flow->nozzle_diameter) * (1 - INSET_OVERLAP_TOLERANCE);
|
||||
double max = 2. * params.flow->scaled_width();
|
||||
// collapse
|
||||
//be sure we don't gapfill where the perimeters are already touching each other (negative spacing).
|
||||
min = std::max(min, double(Flow::new_from_spacing(EPSILON, params.flow->nozzle_diameter, params.flow->height, false).scaled_width()));
|
||||
//ExPolygons gapfill_areas_collapsed = diff_ex(
|
||||
// offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2)),
|
||||
// offset2_ex(gapfill_areas, double(-max / 2), double(+max / 2)),
|
||||
// true);
|
||||
ExPolygons gapfill_areas_collapsed = offset2_ex(gapfill_areas, double(-min / 2), double(+min / 2));
|
||||
for (const ExPolygon &ex : gapfill_areas_collapsed) {
|
||||
//remove too small gaps that are too hard to fill.
|
||||
//ie one that are smaller than an extrusion with width of min and a length of max.
|
||||
if (ex.area() > scale_(params.flow->nozzle_diameter)*scale_(params.flow->nozzle_diameter) * 2) {
|
||||
MedialAxis{ ex, params.flow->scaled_width() * 2, params.flow->scaled_width() / 5, coord_t(params.flow->height) }.build(polylines_gapfill);
|
||||
}
|
||||
}
|
||||
if (!polylines_gapfill.empty() && params.role != erBridgeInfill) {
|
||||
//test
|
||||
#ifdef _DEBUG
|
||||
for (ThickPolyline poly : polylines_gapfill) {
|
||||
for (coordf_t width : poly.width) {
|
||||
if (width > params.flow->scaled_width() * 2.2) {
|
||||
std::cerr << "ERRROR!!!! recti gapfill width = " << unscaled(width) << " > max_width = " << (params.flow->width * 2) << "\n";
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
ExtrusionEntityCollection gap_fill = thin_variable_width(polylines_gapfill, erGapFill, *params.flow);
|
||||
//set role if needed
|
||||
if (params.role != erSolidInfill) {
|
||||
ExtrusionSetRole set_good_role(params.role);
|
||||
gap_fill.visit(set_good_role);
|
||||
}
|
||||
//move them into the collection
|
||||
if (!gap_fill.entities.empty()) {
|
||||
ExtrusionEntityCollection *coll_gapfill = new ExtrusionEntityCollection();
|
||||
coll_gapfill->no_sort = this->no_sort();
|
||||
coll_gapfill->append(std::move(gap_fill.entities));
|
||||
coll_out.push_back(coll_gapfill);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
} // namespace Slic3r
|
||||
|
@ -118,6 +118,7 @@ public:
|
||||
virtual Fill* clone() const { return new FillRectilinear2WGapFill(*this); };
|
||||
virtual ~FillRectilinear2WGapFill() {}
|
||||
virtual void fill_surface_extrusion(const Surface *surface, const FillParams ¶ms, ExtrusionEntitiesPtr &out) override;
|
||||
static void split_polygon_gap_fill(const Surface &surface, const FillParams ¶ms, ExPolygons &rectilinear, ExPolygons &gapfill);
|
||||
};
|
||||
|
||||
|
||||
|
@ -18,7 +18,7 @@ namespace Slic3r {
|
||||
return polylines_out;
|
||||
}
|
||||
|
||||
void FillSmooth::performSingleFill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
|
||||
void FillSmooth::perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
|
||||
const FillParams ¶ms, const double volume){
|
||||
if (srf_source.expolygon.empty()) return;
|
||||
|
||||
@ -26,17 +26,23 @@ namespace Slic3r {
|
||||
ExtrusionEntityCollection *eec = new ExtrusionEntityCollection();
|
||||
eec->no_sort = false;
|
||||
FillParams params_modifided = params;
|
||||
params_modifided.density *= percentWidth[idx];
|
||||
if (params.config != NULL && rolePass[idx] == ExtrusionRole::erTopSolidInfill) params_modifided.density /= (float)params.config->fill_smooth_width.get_abs_value(1);
|
||||
else params_modifided.density *= (float)percentWidth[idx];
|
||||
// reduce flow for each increase in density
|
||||
params_modifided.flow_mult *= params.density;
|
||||
params_modifided.flow_mult /= params_modifided.density;
|
||||
// split the flow between steps
|
||||
params_modifided.flow_mult *= (float)percentFlow[idx];
|
||||
|
||||
if ((params.flow->bridge && idx == 0) || has_overlap[idx]){
|
||||
this->fillExPolygon(idx, *eec, srf_source, params_modifided, volume);
|
||||
this->fill_expolygon(idx, *eec, srf_source, params_modifided, volume);
|
||||
}
|
||||
else{
|
||||
Surface surfaceNoOverlap(srf_source);
|
||||
for (ExPolygon &poly : this->no_overlap_expolygons) {
|
||||
if (poly.empty()) continue;
|
||||
surfaceNoOverlap.expolygon = poly;
|
||||
this->fillExPolygon(idx, *eec, surfaceNoOverlap, params_modifided, volume);
|
||||
this->fill_expolygon(idx, *eec, surfaceNoOverlap, params_modifided, volume);
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +50,7 @@ namespace Slic3r {
|
||||
else eecroot.entities.push_back(eec);
|
||||
}
|
||||
|
||||
void FillSmooth::fillExPolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
|
||||
void FillSmooth::fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
|
||||
const FillParams ¶ms, const double volume){
|
||||
|
||||
std::unique_ptr<Fill> f2 = std::unique_ptr<Fill>(Fill::new_from_type(fillPattern[idx]));
|
||||
@ -59,41 +65,35 @@ namespace Slic3r {
|
||||
f2->loop_clipping = this->loop_clipping;
|
||||
Polylines polylines_layer = f2->fill_surface(&srf_to_fill, params);
|
||||
|
||||
if (!polylines_layer.empty()){
|
||||
/*if (fillPattern[idx] == InfillPattern::ipRectilinear && polylines_layer[0].points.size() > 3){
|
||||
polylines_layer[0].points.erase(polylines_layer[0].points.begin());
|
||||
polylines_layer[polylines_layer.size() - 1].points.pop_back();
|
||||
}*/
|
||||
if (!polylines_layer.empty()) {
|
||||
|
||||
//compute the path of the nozzle
|
||||
double lengthTot = 0;
|
||||
int nbLines = 0;
|
||||
for (Polyline &pline : polylines_layer){
|
||||
for (Polyline &pline : polylines_layer) {
|
||||
Lines lines = pline.lines();
|
||||
for (Line &line : lines){
|
||||
for (Line &line : lines) {
|
||||
lengthTot += unscaled(line.length());
|
||||
nbLines++;
|
||||
}
|
||||
}
|
||||
double extrudedVolume = params.flow->mm3_per_mm() * lengthTot;
|
||||
double extrudedVolume = params.flow->mm3_per_mm() * lengthTot / params.density;
|
||||
if (extrudedVolume == 0) extrudedVolume = volume;
|
||||
|
||||
//get the role
|
||||
ExtrusionRole good_role = params.role;
|
||||
if (good_role == erNone || good_role == erCustom) {
|
||||
good_role = params.flow->bridge && idx==0 ? erBridgeInfill : rolePass[idx];
|
||||
good_role = params.flow->bridge && idx == 0 ? erBridgeInfill : rolePass[idx];
|
||||
}
|
||||
// print thin
|
||||
// print
|
||||
float mult_flow = (params.fill_exactly && idx == 0 ? std::min(2., volume / extrudedVolume) : 1);
|
||||
std::cout << "mult_flow =" << mult_flow << " \n";
|
||||
extrusion_entities_append_paths(
|
||||
eec.entities, std::move(polylines_layer),
|
||||
good_role,
|
||||
params.flow_mult * params.flow->mm3_per_mm() * percentFlow[idx] *
|
||||
(params.fill_exactly ? std::min(2., volume / extrudedVolume) : 1),
|
||||
params.flow_mult * params.flow->mm3_per_mm() * mult_flow,
|
||||
//min-reduced flow width for a better view (it's only a gui thing)
|
||||
(float)(params.flow->width*(percentFlow[idx] < 0.1 ? 0.1 : percentFlow[idx])), (float)params.flow->height);
|
||||
}
|
||||
else{
|
||||
return;
|
||||
(float)(params.flow->width * (params.flow_mult* mult_flow < 0.1 ? 0.1 : params.flow_mult * mult_flow)), (float)params.flow->height);
|
||||
}
|
||||
}
|
||||
|
||||
@ -118,28 +118,23 @@ namespace Slic3r {
|
||||
//extruded volume: see http://manual.slic3r.org/advanced/flow-math, and we need to remove a circle at an end (as the flow continue)
|
||||
volumeToOccupy += poylineVolume;
|
||||
}
|
||||
//if (polylines_layer1.empty() && polylines_layer2.empty() && polylines_layer3.empty())
|
||||
// return;
|
||||
|
||||
//create root node
|
||||
ExtrusionEntityCollection *eecroot = new ExtrusionEntityCollection();
|
||||
//you don't want to sort the extrusions: big infill first, small second
|
||||
eecroot->no_sort = true;
|
||||
|
||||
ExtrusionEntityCollection *eec;
|
||||
|
||||
|
||||
// first infill
|
||||
performSingleFill(0, *eecroot, *surface, params, volumeToOccupy);
|
||||
perform_single_fill(0, *eecroot, *surface, params, volumeToOccupy);
|
||||
|
||||
//second infill
|
||||
if (nbPass > 1){
|
||||
performSingleFill(1, *eecroot, *surface, params, volumeToOccupy);
|
||||
perform_single_fill(1, *eecroot, *surface, params, volumeToOccupy);
|
||||
}
|
||||
|
||||
// third infill
|
||||
if (nbPass > 2){
|
||||
performSingleFill(2, *eecroot, *surface, params, volumeToOccupy);
|
||||
perform_single_fill(2, *eecroot, *surface, params, volumeToOccupy);
|
||||
}
|
||||
|
||||
if (!eecroot->entities.empty())
|
||||
|
@ -15,17 +15,17 @@ public:
|
||||
anglePass[0] = 0;
|
||||
anglePass[1] = float(M_PI/2);
|
||||
anglePass[2] = 0;
|
||||
fillPattern[0] = InfillPattern::ipRectilinear;
|
||||
fillPattern[0] = InfillPattern::ipRectilinearWGapFill;
|
||||
fillPattern[1] = InfillPattern::ipRectilinear;
|
||||
fillPattern[2] = InfillPattern::ipRectilinear;
|
||||
rolePass[0] = erSolidInfill;
|
||||
rolePass[1] = erTopSolidInfill;
|
||||
rolePass[2] = erSolidInfill;
|
||||
percentWidth[0] = 0.9;
|
||||
rolePass[2] = erTopSolidInfill;
|
||||
percentWidth[0] = 1;
|
||||
percentWidth[1] = 2;
|
||||
percentWidth[2] = 1.0;
|
||||
percentFlow[0] = 0.7;
|
||||
percentFlow[1] = 0.3;
|
||||
percentFlow[0] = 0.8;
|
||||
percentFlow[1] = 0.2;
|
||||
percentFlow[2] = 0.0;
|
||||
double extrusionMult = 1.0;
|
||||
percentFlow[0] *= extrusionMult;
|
||||
@ -42,16 +42,22 @@ public:
|
||||
|
||||
protected:
|
||||
int nbPass=2;
|
||||
// this parameter is now erased by fill_smooth_width when available.
|
||||
double percentWidth[3];
|
||||
// this parameter is now modified by fill_top_flow_ratio when available.
|
||||
double percentFlow[3];
|
||||
//angle to add to base angle
|
||||
float anglePass[3];
|
||||
//if false, it won't overlap inside the perimeters
|
||||
bool has_overlap[3];
|
||||
// profile for base width, speed, etc.
|
||||
ExtrusionRole rolePass[3];
|
||||
//fill algorithm to call
|
||||
InfillPattern fillPattern[3];
|
||||
|
||||
void performSingleFill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
|
||||
void perform_single_fill(const int idx, ExtrusionEntityCollection &eecroot, const Surface &srf_source,
|
||||
const FillParams ¶ms, const double volume);
|
||||
void fillExPolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
|
||||
void fill_expolygon(const int idx, ExtrusionEntityCollection &eec, const Surface &srf_to_fill,
|
||||
const FillParams ¶ms, const double volume);
|
||||
};
|
||||
|
||||
|
@ -205,7 +205,7 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionInts{ 100 });
|
||||
|
||||
def = this->add("bridge_flow_ratio", coFloat);
|
||||
def = this->add("bridge_flow_ratio", coFloatOrPercent);
|
||||
def->label = L("Bridge");
|
||||
def->full_label = L("Bridge flow ratio");
|
||||
def->category = L("Advanced");
|
||||
@ -216,18 +216,18 @@ void PrintConfigDef::init_fff_params()
|
||||
def->min = 0;
|
||||
def->max = 2;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(1));
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(100, true));
|
||||
|
||||
def = this->add("over_bridge_flow_ratio", coFloat);
|
||||
def = this->add("over_bridge_flow_ratio", coFloatOrPercent);
|
||||
def->label = L("Above the bridges");
|
||||
def->full_label = L("Above bridge flow ratio");
|
||||
def->category = L("Advanced");
|
||||
def->tooltip = L("Flow ratio to compensate for the gaps in a bridged top surface. Used for ironing infill"
|
||||
"pattern to prevent regions where the low-flow pass does not provide a smooth surface due to a lack of plastic."
|
||||
" You can increase it slightly to pull the top layer at the correct height. Recommended maximum: 1.2.");
|
||||
" You can increase it slightly to pull the top layer at the correct height. Recommended maximum: 120%.");
|
||||
def->min = 0;
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(1));
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(100, true));
|
||||
|
||||
def = this->add("bridge_speed", coFloat);
|
||||
def->label = L("Bridges");
|
||||
@ -1145,6 +1145,22 @@ void PrintConfigDef::init_fff_params()
|
||||
def->enum_labels.push_back(L("Scattered Rectilinear"));
|
||||
def->set_default_value( new ConfigOptionEnum<InfillPattern>(ipStars));
|
||||
|
||||
def = this->add("fill_top_flow_ratio", coFloatOrPercent);
|
||||
def->label = L(" Top fill");
|
||||
def->full_label = L("Top fill flow");
|
||||
def->tooltip = L("You can increase this to over-extrude on the top layer if there are not enough plastic to makle a fill.");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(100, true));
|
||||
|
||||
def = this->add("fill_smooth_width", coFloatOrPercent);
|
||||
def->label = L("width");
|
||||
def->full_label = L("Ironing width");
|
||||
def->tooltip = L("This is the width of the ironing pass, in a % of the top width, should be no more than 50%.");
|
||||
def->min = 0;
|
||||
def->mode = comExpert;
|
||||
def->set_default_value(new ConfigOptionFloatOrPercent(50, true));
|
||||
|
||||
def = this->add("first_layer_acceleration", coFloat);
|
||||
def->label = L("First layer");
|
||||
def->full_label = L("First layer acceleration");
|
||||
@ -3756,14 +3772,6 @@ std::string FullPrintConfig::validate()
|
||||
// --skirt-height
|
||||
if (this->skirt_height < -1) // -1 means as tall as the object
|
||||
return "Invalid value for --skirt-height";
|
||||
|
||||
// --bridge-flow-ratio
|
||||
if (this->bridge_flow_ratio <= 0)
|
||||
return "Invalid value for --bridge-flow-ratio";
|
||||
|
||||
// --over-bridge-flow-ratio
|
||||
if (this->over_bridge_flow_ratio <= 0)
|
||||
return "Invalid value for --over-bridge-flow-ratio";
|
||||
|
||||
// extruder clearance
|
||||
if (this->extruder_clearance_radius <= 0)
|
||||
@ -3824,21 +3832,32 @@ std::string FullPrintConfig::validate()
|
||||
bool out_of_range = false;
|
||||
switch (opt->type()) {
|
||||
case coFloat:
|
||||
case coPercent:
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
auto *fopt = static_cast<const ConfigOptionFloat*>(opt);
|
||||
out_of_range = fopt->value < optdef->min || fopt->value > optdef->max;
|
||||
break;
|
||||
}
|
||||
case coPercent:
|
||||
case coFloatOrPercent:
|
||||
{
|
||||
auto *fopt = static_cast<const ConfigOptionPercent*>(opt);
|
||||
out_of_range = fopt->get_abs_value(1) < optdef->min || fopt->get_abs_value(1) > optdef->max;
|
||||
break;
|
||||
}
|
||||
case coFloats:
|
||||
case coPercents:
|
||||
for (double v : static_cast<const ConfigOptionVector<double>*>(opt)->values)
|
||||
if (v < optdef->min || v > optdef->max) {
|
||||
out_of_range = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case coPercents:
|
||||
for (double v : static_cast<const ConfigOptionVector<double>*>(opt)->values)
|
||||
if (v*0.01 < optdef->min || v * 0.01 > optdef->max) {
|
||||
out_of_range = true;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case coInt:
|
||||
{
|
||||
auto *iopt = static_cast<const ConfigOptionInt*>(opt);
|
||||
|
@ -571,8 +571,8 @@ class PrintRegionConfig : public StaticPrintConfig
|
||||
public:
|
||||
ConfigOptionFloat bridge_angle;
|
||||
ConfigOptionInt bottom_solid_layers;
|
||||
ConfigOptionFloat bridge_flow_ratio;
|
||||
ConfigOptionFloat over_bridge_flow_ratio;
|
||||
ConfigOptionFloatOrPercent bridge_flow_ratio;
|
||||
ConfigOptionFloatOrPercent over_bridge_flow_ratio;
|
||||
ConfigOptionEnum<InfillPattern> bottom_fill_pattern;
|
||||
ConfigOptionFloatOrPercent bridged_infill_margin;
|
||||
ConfigOptionFloat bridge_speed;
|
||||
@ -591,6 +591,8 @@ public:
|
||||
ConfigOptionFloat fill_angle;
|
||||
ConfigOptionPercent fill_density;
|
||||
ConfigOptionEnum<InfillPattern> fill_pattern;
|
||||
ConfigOptionFloatOrPercent fill_top_flow_ratio;
|
||||
ConfigOptionFloatOrPercent fill_smooth_width;
|
||||
ConfigOptionBool gap_fill;
|
||||
ConfigOptionFloatOrPercent gap_fill_min_area;
|
||||
ConfigOptionFloat gap_fill_speed;
|
||||
@ -655,6 +657,8 @@ protected:
|
||||
OPT_PTR(fill_angle);
|
||||
OPT_PTR(fill_density);
|
||||
OPT_PTR(fill_pattern);
|
||||
OPT_PTR(fill_top_flow_ratio);
|
||||
OPT_PTR(fill_smooth_width);
|
||||
OPT_PTR(gap_fill);
|
||||
OPT_PTR(gap_fill_min_area);
|
||||
OPT_PTR(gap_fill_speed);
|
||||
|
@ -558,6 +558,8 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
|| opt_key == "enforce_full_fill_volume"
|
||||
|| opt_key == "fill_angle"
|
||||
|| opt_key == "fill_pattern"
|
||||
|| opt_key == "fill_top_flow_ratio"
|
||||
|| opt_key == "fill_smooth_width"
|
||||
|| opt_key == "top_infill_extrusion_width"
|
||||
|| opt_key == "first_layer_extrusion_width") {
|
||||
steps.emplace_back(posInfill);
|
||||
@ -1683,7 +1685,7 @@ PrintObject::replaceSurfaceType(SurfaceType st_to_replace, SurfaceType st_replac
|
||||
const PrintRegion ®ion = *m_print->regions()[region_id];
|
||||
|
||||
// skip over-bridging in case there are no modification
|
||||
if (region.config().over_bridge_flow_ratio.value == 1) continue;
|
||||
if (region.config().over_bridge_flow_ratio.get_abs_value(1) == 1) continue;
|
||||
|
||||
for (LayerPtrs::iterator layer_it = m_layers.begin(); layer_it != m_layers.end(); ++layer_it) {
|
||||
// skip first layer
|
||||
|
@ -50,7 +50,7 @@ Flow PrintRegion::flow(FlowRole role, double layer_height, bool bridge, bool fir
|
||||
// Get the configured nozzle_diameter for the extruder associated to the flow role requested.
|
||||
// Here this->extruder(role) - 1 may underflow to MAX_INT, but then the get_at() will follback to zero'th element, so everything is all right.
|
||||
double nozzle_diameter = m_print->config().nozzle_diameter.get_at(this->extruder(role) - 1);
|
||||
return Flow::new_from_config_width(role, config_width, (float)nozzle_diameter, (float)layer_height, bridge ? (float)m_config.bridge_flow_ratio : 0.0f);
|
||||
return Flow::new_from_config_width(role, config_width, (float)nozzle_diameter, (float)layer_height, bridge ? (float)m_config.bridge_flow_ratio.get_abs_value(1) : 0.0f);
|
||||
}
|
||||
|
||||
coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
|
||||
@ -62,7 +62,7 @@ coordf_t PrintRegion::nozzle_dmr_avg(const PrintConfig &print_config) const
|
||||
|
||||
coordf_t PrintRegion::bridging_height_avg(const PrintConfig &print_config) const
|
||||
{
|
||||
return this->nozzle_dmr_avg(print_config) * sqrt(m_config.bridge_flow_ratio.value);
|
||||
return this->nozzle_dmr_avg(print_config) * sqrt(m_config.bridge_flow_ratio.get_abs_value(1));
|
||||
}
|
||||
|
||||
void PrintRegion::collect_object_printing_extruders(const PrintConfig &print_config, const PrintRegionConfig ®ion_config, std::vector<unsigned int> &object_extruders)
|
||||
|
@ -279,6 +279,9 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
// gap fill can appear in infill
|
||||
//toggle_field("gap_fill_speed", have_perimeters && config->opt_bool("gap_fill"));
|
||||
|
||||
for (auto el : {"fill_smooth_width" })
|
||||
toggle_field(el, config->opt_enum<InfillPattern>("top_fill_pattern") == InfillPattern::ipSmooth);
|
||||
|
||||
bool have_top_solid_infill = config->opt_int("top_solid_layers") > 0;
|
||||
for (auto el : { "top_infill_extrusion_width", "top_solid_infill_speed" })
|
||||
toggle_field(el, have_top_solid_infill);
|
||||
|
@ -382,6 +382,8 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"extra_perimeters", "only_one_perimeter_top", "ensure_vertical_shell_thickness", "avoid_crossing_perimeters", "thin_walls", "overhangs",
|
||||
"seam_position", "external_perimeters_first", "fill_density"
|
||||
, "fill_pattern"
|
||||
, "fill_top_flow_ratio"
|
||||
, "fill_smooth_width"
|
||||
, "top_fill_pattern"
|
||||
, "bottom_fill_pattern"
|
||||
, "solid_fill_pattern",
|
||||
|
@ -1125,9 +1125,9 @@ void TabPrint::build()
|
||||
line.append_option(optgroup->get_option("infill_dense_algo"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Advanced")));
|
||||
optgroup->append_single_option_line("solid_infill_every_layers");
|
||||
optgroup->append_single_option_line("solid_infill_below_area");
|
||||
optgroup = page->new_optgroup(_(L("Advanced")));
|
||||
optgroup->append_single_option_line("solid_infill_every_layers");
|
||||
optgroup->append_single_option_line("solid_infill_below_area");
|
||||
line = { _(L("Angle")), "" };
|
||||
line.append_option(optgroup->get_option("fill_angle"));
|
||||
line.append_option(optgroup->get_option("bridge_angle"));
|
||||
@ -1136,8 +1136,13 @@ void TabPrint::build()
|
||||
line.append_option(optgroup->get_option("external_infill_margin"));
|
||||
line.append_option(optgroup->get_option("bridged_infill_margin"));
|
||||
optgroup->append_line(line);
|
||||
optgroup->append_single_option_line("only_retract_when_crossing_perimeters");
|
||||
optgroup->append_single_option_line("only_retract_when_crossing_perimeters");
|
||||
optgroup->append_single_option_line("infill_first");
|
||||
line = { _(L("Ironing tuning")), "" };
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Advanced Infill")));
|
||||
line.append_option(optgroup->get_option("fill_smooth_width"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
page = add_options_page(_(L("Skirt and brim")), "skirt+brim");
|
||||
optgroup = page->new_optgroup(_(L("Skirt")));
|
||||
@ -1229,24 +1234,25 @@ void TabPrint::build()
|
||||
optgroup->append_single_option_line("max_volumetric_extrusion_rate_slope_negative");
|
||||
#endif /* HAS_PRESSURE_EQUALIZER */
|
||||
|
||||
page = add_options_page(_(L("Width & flow")), "width");
|
||||
optgroup = page->new_optgroup(_(L("Extrusion width")));
|
||||
optgroup->append_single_option_line("extrusion_width");
|
||||
optgroup->append_single_option_line("first_layer_extrusion_width");
|
||||
optgroup->append_single_option_line("perimeter_extrusion_width");
|
||||
optgroup->append_single_option_line("external_perimeter_extrusion_width");
|
||||
optgroup->append_single_option_line("infill_extrusion_width");
|
||||
optgroup->append_single_option_line("solid_infill_extrusion_width");
|
||||
optgroup->append_single_option_line("top_infill_extrusion_width");
|
||||
optgroup->append_single_option_line("support_material_extrusion_width");
|
||||
page = add_options_page(_(L("Width & flow")), "width");
|
||||
optgroup = page->new_optgroup(_(L("Extrusion width")));
|
||||
optgroup->append_single_option_line("extrusion_width");
|
||||
optgroup->append_single_option_line("first_layer_extrusion_width");
|
||||
optgroup->append_single_option_line("perimeter_extrusion_width");
|
||||
optgroup->append_single_option_line("external_perimeter_extrusion_width");
|
||||
optgroup->append_single_option_line("infill_extrusion_width");
|
||||
optgroup->append_single_option_line("solid_infill_extrusion_width");
|
||||
optgroup->append_single_option_line("top_infill_extrusion_width");
|
||||
optgroup->append_single_option_line("support_material_extrusion_width");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Overlap")));
|
||||
optgroup->append_single_option_line("infill_overlap");
|
||||
optgroup = page->new_optgroup(_(L("Overlap")));
|
||||
optgroup->append_single_option_line("infill_overlap");
|
||||
|
||||
optgroup = page->new_optgroup(_(L("Flow")));
|
||||
line = { _(L("Flow ratio")), "" };
|
||||
line.append_option(optgroup->get_option("bridge_flow_ratio"));
|
||||
line.append_option(optgroup->get_option("over_bridge_flow_ratio"));
|
||||
line.append_option(optgroup->get_option("fill_top_flow_ratio"));
|
||||
optgroup->append_line(line);
|
||||
|
||||
page = add_options_page(_(L("Multiple extruders")), "funnel");
|
||||
|
@ -310,7 +310,7 @@ SCENARIO("thin walls: ")
|
||||
REQUIRE(std::abs(max_width - nozzle_diam) > SCALED_EPSILON);
|
||||
}
|
||||
//compute the length of the tapers
|
||||
THEN("medial axis has a 45° taper and a shorter one") {
|
||||
THEN("medial axis has a 45<EFBFBD> taper and a shorter one") {
|
||||
int l1 = 0;
|
||||
for (size_t idx = 0; idx < res[0].width.size() - 1 && res[0].width[idx] - scale_(1.2) < SCALED_EPSILON; ++idx)
|
||||
l1 += res[0].lines()[idx].length();
|
||||
@ -328,7 +328,7 @@ SCENARIO("thin walls: ")
|
||||
|
||||
}
|
||||
|
||||
GIVEN("1° rotated tooths")
|
||||
GIVEN("1<EFBFBD> rotated tooths")
|
||||
{
|
||||
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user