mirror of
https://git.mirrors.martin98.com/https://github.com/slic3r/Slic3r.git
synced 2025-07-13 04:41:46 +08:00
#399 add an other pattern for brim ear: rectilinear with perimeter.
If you have problem with adhesion of the ear. also some fixes about brim invalidation.
This commit is contained in:
parent
c36681147d
commit
3ec2f077e5
@ -154,6 +154,7 @@ group:Brim
|
||||
line:Brim ears
|
||||
setting:brim_ears
|
||||
setting:width$3:brim_ears_max_angle
|
||||
setting:brim_ears_pattern
|
||||
end_line
|
||||
setting:brim_offset
|
||||
|
||||
|
@ -898,7 +898,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
|
||||
surface->expolygon,
|
||||
- rotate_vector.first,
|
||||
scale_(0 /*this->overlap*/ - (0.5 - INFILL_OVERLAP_OVER_SPACING) * this->spacing),
|
||||
scale_(0 /*this->overlap*/ - 0.5 * this->spacing));
|
||||
scale_(0 /*this->overlap*/ - (params.full_infill() && params.fill_exactly ? 0.5 + INFILL_OVERLAP_OVER_SPACING : 0.5) * this->spacing));
|
||||
if (poly_with_offset.n_contours_inner == 0) {
|
||||
// Not a single infill line fits.
|
||||
//Prusa: maybe one shall trigger the gap fill here?
|
||||
@ -909,7 +909,7 @@ bool FillRectilinear2::fill_surface_by_lines(const Surface *surface, const FillP
|
||||
BoundingBox bounding_box = poly_with_offset.bounding_box_src();
|
||||
|
||||
// define flow spacing according to requested density
|
||||
if (params.full_infill() && !params.dont_adjust) {
|
||||
if (params.full_infill() && !params.dont_adjust || line_spacing == 0 ) {
|
||||
//it's == this->_adjust_solid_spacing(bounding_box.size()(0), line_spacing) because of the init_spacing
|
||||
line_spacing = scale_(this->spacing);
|
||||
} else {
|
||||
|
@ -5,6 +5,7 @@
|
||||
#include "ClipperUtils.hpp"
|
||||
#include "Extruder.hpp"
|
||||
#include "Flow.hpp"
|
||||
#include "Fill/FillBase.hpp"
|
||||
#include "Geometry.hpp"
|
||||
#include "I18N.hpp"
|
||||
#include "ShortestPath.hpp"
|
||||
@ -196,8 +197,11 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|
||||
} else if (
|
||||
opt_key == "brim_inside_holes"
|
||||
|| opt_key == "brim_width"
|
||||
|| opt_key == "brim_width_interior"
|
||||
|| opt_key == "brim_offset"
|
||||
|| opt_key == "brim_ears"
|
||||
|| opt_key == "brim_ears_max_angle") {
|
||||
|| opt_key == "brim_ears_max_angle"
|
||||
|| opt_key == "brim_ears_pattern") {
|
||||
steps.emplace_back(psBrim);
|
||||
steps.emplace_back(psSkirt);
|
||||
} else if (
|
||||
@ -1712,6 +1716,7 @@ void Print::process()
|
||||
for (std::vector<PrintObject*> &obj_group : obj_groups) {
|
||||
if (obj_group.front()->config().brim_ears.value == obj->config().brim_ears.value
|
||||
&& obj_group.front()->config().brim_ears_max_angle.value == obj->config().brim_ears_max_angle.value
|
||||
&& obj_group.front()->config().brim_ears_pattern.value == obj->config().brim_ears_pattern.value
|
||||
&& obj_group.front()->config().brim_inside_holes.value == obj->config().brim_inside_holes.value
|
||||
&& obj_group.front()->config().brim_offset.value == obj->config().brim_offset.value
|
||||
&& obj_group.front()->config().brim_width.value == obj->config().brim_width.value
|
||||
@ -2281,61 +2286,102 @@ void Print::_make_brim_ears(const Flow &flow, const PrintObjectPtrs &objects, Ex
|
||||
brimmable_areas = diff_ex(brimmable_areas, unbrimmable, true);
|
||||
|
||||
this->throw_if_canceled();
|
||||
//create loops (same as standard brim)
|
||||
Polygons loops;
|
||||
islands = offset_ex(islands, -0.5f * double(flow.scaled_spacing()));
|
||||
for (size_t i = 0; i < num_loops; ++i) {
|
||||
this->throw_if_canceled();
|
||||
islands = offset_ex(islands, double(flow.scaled_spacing()), jtSquare);
|
||||
for (ExPolygon &expoly : islands) {
|
||||
Polygon poly = expoly.contour;
|
||||
poly.points.push_back(poly.points.front());
|
||||
Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
|
||||
p.pop_back();
|
||||
poly.points = std::move(p);
|
||||
loops.push_back(poly);
|
||||
|
||||
if (brim_config.brim_ears_pattern.value == InfillPattern::ipConcentric) {
|
||||
|
||||
//create loops (same as standard brim)
|
||||
Polygons loops;
|
||||
islands = offset_ex(islands, -0.5f * double(flow.scaled_spacing()));
|
||||
for (size_t i = 0; i < num_loops; ++i) {
|
||||
this->throw_if_canceled();
|
||||
islands = offset_ex(islands, double(flow.scaled_spacing()), jtSquare);
|
||||
for (ExPolygon &expoly : islands) {
|
||||
Polygon poly = expoly.contour;
|
||||
poly.points.push_back(poly.points.front());
|
||||
Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
|
||||
p.pop_back();
|
||||
poly.points = std::move(p);
|
||||
loops.push_back(poly);
|
||||
}
|
||||
}
|
||||
}
|
||||
//order path with least travel possible
|
||||
loops = union_pt_chained(loops, false);
|
||||
//order path with least travel possible
|
||||
loops = union_pt_chained(loops, false);
|
||||
|
||||
//create ear pattern
|
||||
coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
|
||||
Polygon point_round;
|
||||
for (size_t i = 0; i < POLY_SIDES; i++) {
|
||||
double angle = (2.0 * PI * i) / POLY_SIDES;
|
||||
point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
|
||||
//create ear pattern
|
||||
coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
|
||||
Polygon point_round;
|
||||
for (size_t i = 0; i < POLY_SIDES; i++) {
|
||||
double angle = (2.0 * PI * i) / POLY_SIDES;
|
||||
point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
|
||||
}
|
||||
|
||||
//create ears
|
||||
Polygons mouse_ears;
|
||||
ExPolygons mouse_ears_ex;
|
||||
for (Point pt : pt_ears) {
|
||||
mouse_ears.push_back(point_round);
|
||||
mouse_ears.back().translate(pt);
|
||||
mouse_ears_ex.emplace_back();
|
||||
mouse_ears_ex.back().contour = mouse_ears.back();
|
||||
}
|
||||
|
||||
//intersection
|
||||
Polylines lines = intersection_pl(loops, mouse_ears);
|
||||
this->throw_if_canceled();
|
||||
|
||||
//reorder & extrude them
|
||||
Polylines lines_sorted = _reorder_brim_polyline(lines, out, flow);
|
||||
|
||||
//push into extrusions
|
||||
extrusion_entities_append_paths(
|
||||
out.entities,
|
||||
lines_sorted,
|
||||
erSkirt,
|
||||
float(flow.mm3_per_mm()),
|
||||
float(flow.width),
|
||||
float(this->skirt_first_layer_height())
|
||||
);
|
||||
|
||||
ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
|
||||
unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
|
||||
} else {
|
||||
|
||||
|
||||
//create ear pattern
|
||||
coord_t size_ear = (scale_((brim_config.brim_width.value - brim_config.brim_offset.value)) - flow.scaled_spacing());
|
||||
Polygon point_round;
|
||||
for (size_t i = 0; i < POLY_SIDES; i++) {
|
||||
double angle = (2.0 * PI * i) / POLY_SIDES;
|
||||
point_round.points.emplace_back(size_ear * cos(angle), size_ear * sin(angle));
|
||||
}
|
||||
|
||||
//create ears
|
||||
ExPolygons mouse_ears_ex;
|
||||
for (Point pt : pt_ears) {
|
||||
mouse_ears_ex.emplace_back();
|
||||
mouse_ears_ex.back().contour = point_round;
|
||||
mouse_ears_ex.back().contour.translate(pt);
|
||||
}
|
||||
|
||||
ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
|
||||
|
||||
std::unique_ptr<Fill> filler = std::unique_ptr<Fill>(Fill::new_from_type(ipRectiWithPerimeter));
|
||||
filler->angle = 0;
|
||||
|
||||
FillParams fill_params;
|
||||
fill_params.density = 1.f;
|
||||
fill_params.fill_exactly = true;
|
||||
fill_params.flow = &flow;
|
||||
fill_params.role = erSkirt;
|
||||
filler->init_spacing(flow.spacing(), fill_params);
|
||||
for (const ExPolygon &expoly : new_brim_area) {
|
||||
Surface surface(stPosInternal | stDensSparse, expoly);
|
||||
filler->fill_surface_extrusion(&surface, fill_params, out.entities);
|
||||
}
|
||||
|
||||
unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
|
||||
}
|
||||
|
||||
//create ears
|
||||
Polygons mouse_ears;
|
||||
ExPolygons mouse_ears_ex;
|
||||
for (Point pt : pt_ears) {
|
||||
mouse_ears.push_back(point_round);
|
||||
mouse_ears.back().translate(pt);
|
||||
mouse_ears_ex.emplace_back();
|
||||
mouse_ears_ex.back().contour = mouse_ears.back();
|
||||
}
|
||||
|
||||
//intersection
|
||||
Polylines lines = intersection_pl(loops, mouse_ears);
|
||||
this->throw_if_canceled();
|
||||
|
||||
//reorder & extrude them
|
||||
Polylines lines_sorted = _reorder_brim_polyline(lines, out, flow);
|
||||
|
||||
//push into extrusions
|
||||
extrusion_entities_append_paths(
|
||||
out.entities,
|
||||
lines_sorted,
|
||||
erSkirt,
|
||||
float(flow.mm3_per_mm()),
|
||||
float(flow.width),
|
||||
float(this->skirt_first_layer_height())
|
||||
);
|
||||
|
||||
ExPolygons new_brim_area = intersection_ex(brimmable_areas, mouse_ears_ex);
|
||||
unbrimmable.insert(unbrimmable.end(), new_brim_area.begin(), new_brim_area.end());
|
||||
}
|
||||
|
||||
void Print::_make_brim_interior(const Flow &flow, const PrintObjectPtrs &objects, ExPolygons &unbrimmable_areas, ExtrusionEntityCollection &out) {
|
||||
|
@ -352,6 +352,19 @@ void PrintConfigDef::init_fff_params()
|
||||
def->mode = comAdvanced;
|
||||
def->set_default_value(new ConfigOptionFloat(125));
|
||||
|
||||
def = this->add("brim_ears_pattern", coEnum);
|
||||
def->label = L("Pattern");
|
||||
def->full_label = L("Ear pattern");
|
||||
def->category = OptionCategory::infill;
|
||||
def->tooltip = L("Pattern for the ear. The concentric id the default one."
|
||||
" The rectilinear has a perimeter around it, you can try it if the concentric has too many problems to stick to the build plate.");
|
||||
def->enum_keys_map = &ConfigOptionEnum<InfillPattern>::get_enum_values();
|
||||
def->enum_values.push_back("concentric");
|
||||
def->enum_values.push_back("rectilinear");
|
||||
def->enum_labels.push_back(L("Concentric"));
|
||||
def->enum_labels.push_back(L("Rectilinear"));
|
||||
def->set_default_value(new ConfigOptionEnum<InfillPattern>(ipConcentric));
|
||||
|
||||
def = this->add("brim_offset", coFloat);
|
||||
def->label = L("brim offset");
|
||||
def->category = OptionCategory::skirtBrim;
|
||||
@ -4736,6 +4749,10 @@ std::string FullPrintConfig::validate()
|
||||
if (!print_config_def.get("solid_fill_pattern")->has_enum_value(this->solid_fill_pattern.serialize()))
|
||||
return "Invalid value for --solid-fill-pattern";
|
||||
|
||||
// --brim-ears-pattern
|
||||
if (!print_config_def.get("brim_ears_pattern")->has_enum_value(this->brim_ears_pattern.serialize()))
|
||||
return "Invalid value for --brim-ears-pattern";
|
||||
|
||||
// --fill-density
|
||||
if (fabs(this->fill_density.value - 100.) < EPSILON &&
|
||||
(! print_config_def.get("top_fill_pattern")->has_enum_value(this->fill_pattern.serialize())
|
||||
|
@ -490,6 +490,7 @@ public:
|
||||
ConfigOptionFloat brim_width_interior;
|
||||
ConfigOptionBool brim_ears;
|
||||
ConfigOptionFloat brim_ears_max_angle;
|
||||
ConfigOptionEnum<InfillPattern> brim_ears_pattern;
|
||||
ConfigOptionFloat brim_offset;
|
||||
ConfigOptionBool clip_multipart_objects;
|
||||
ConfigOptionBool dont_support_bridges;
|
||||
@ -555,6 +556,7 @@ protected:
|
||||
OPT_PTR(brim_width_interior);
|
||||
OPT_PTR(brim_ears);
|
||||
OPT_PTR(brim_ears_max_angle);
|
||||
OPT_PTR(brim_ears_pattern);
|
||||
OPT_PTR(brim_offset);
|
||||
OPT_PTR(clip_multipart_objects);
|
||||
OPT_PTR(dont_support_bridges);
|
||||
|
@ -757,6 +757,15 @@ bool PrintObject::invalidate_state_by_config_options(const std::vector<t_config_
|
||||
|| opt_key == "wipe_into_objects") {
|
||||
invalidated |= m_print->invalidate_step(psWipeTower);
|
||||
invalidated |= m_print->invalidate_step(psGCodeExport);
|
||||
} else if (
|
||||
opt_key == "brim_inside_holes"
|
||||
|| opt_key == "brim_width"
|
||||
|| opt_key == "brim_width_interior"
|
||||
|| opt_key == "brim_offset"
|
||||
|| opt_key == "brim_ears"
|
||||
|| opt_key == "brim_ears_max_angle"
|
||||
|| opt_key == "brim_ears_pattern") {
|
||||
invalidated |= m_print->invalidate_step(psBrim);
|
||||
} else {
|
||||
// for legacy, if we can't handle this option let's invalidate all steps
|
||||
this->invalidate_all_steps();
|
||||
|
@ -376,6 +376,7 @@ void ConfigManipulation::toggle_print_fff_options(DynamicPrintConfig* config)
|
||||
toggle_field("brim_ears", config->opt_float("brim_width") > 0);
|
||||
toggle_field("brim_inside_holes", config->opt_float("brim_width") > 0 && config->opt_float("brim_width_interior") == 0);
|
||||
toggle_field("brim_ears_max_angle", have_brim && config->opt_bool("brim_ears"));
|
||||
toggle_field("brim_ears_pattern", have_brim && config->opt_bool("brim_ears"));
|
||||
|
||||
bool have_raft = config->opt_int("raft_layers") > 0;
|
||||
bool have_support_material = config->opt_bool("support_material") || have_raft;
|
||||
|
@ -986,7 +986,7 @@ void Choice::set_value(const boost::any& value, bool change_event)
|
||||
case coEnum: {
|
||||
int val = boost::any_cast<int>(value);
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "solid_fill_pattern"
|
||||
|| m_opt_id == "fill_pattern" || m_opt_id == "support_material_interface_pattern")
|
||||
|| m_opt_id == "fill_pattern" || m_opt_id == "support_material_interface_pattern" || m_opt_id == "brim_ears_pattern")
|
||||
{
|
||||
val = idx_from_enum_value<InfillPattern>(val);
|
||||
} else if (m_opt_id.compare("perimeter_loop_seam") == 0) {
|
||||
@ -1073,7 +1073,7 @@ boost::any& Choice::get_value()
|
||||
{
|
||||
int ret_enum = field->GetSelection();
|
||||
if (m_opt_id == "top_fill_pattern" || m_opt_id == "bottom_fill_pattern" || m_opt_id == "solid_fill_pattern"
|
||||
|| m_opt_id == "support_material_interface_pattern" || m_opt_id == "fill_pattern")
|
||||
|| m_opt_id == "support_material_interface_pattern" || m_opt_id == "fill_pattern" || m_opt_id == "brim_ears_pattern")
|
||||
convert_to_enum_value<InfillPattern>(ret_enum);
|
||||
else if (m_opt_id.compare("gcode_flavor") == 0)
|
||||
convert_to_enum_value<GCodeFlavor>(ret_enum);
|
||||
|
@ -187,7 +187,8 @@ void change_opt_value(DynamicPrintConfig& config, const t_config_option_key& opt
|
||||
if (opt_key == "top_fill_pattern" ||
|
||||
opt_key == "bottom_fill_pattern" ||
|
||||
opt_key == "solid_fill_pattern" ||
|
||||
opt_key == "fill_pattern")
|
||||
opt_key == "fill_pattern" ||
|
||||
opt_key == "brim_ears_pattern")
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<InfillPattern>(boost::any_cast<InfillPattern>(value)));
|
||||
else if (opt_key.compare("complete_objects_sort") == 0)
|
||||
config.set_key_value(opt_key, new ConfigOptionEnum<CompleteObjectSort>(boost::any_cast<CompleteObjectSort>(value)));
|
||||
|
@ -746,7 +746,8 @@ boost::any ConfigOptionsGroup::get_config_value(const DynamicPrintConfig& config
|
||||
if (opt_key == "top_fill_pattern" ||
|
||||
opt_key == "bottom_fill_pattern" ||
|
||||
opt_key == "solid_fill_pattern" ||
|
||||
opt_key == "fill_pattern" ) {
|
||||
opt_key == "fill_pattern" ||
|
||||
opt_key == "brim_ears_pattern" ) {
|
||||
ret = static_cast<int>(config.option<ConfigOptionEnum<InfillPattern>>(opt_key)->value);
|
||||
}
|
||||
else if (opt_key.compare("complete_objects_sort") == 0 ) {
|
||||
|
@ -485,6 +485,7 @@ const std::vector<std::string>& Preset::print_options()
|
||||
"brim_width_interior",
|
||||
"brim_ears",
|
||||
"brim_ears_max_angle",
|
||||
"brim_ears_pattern",
|
||||
"brim_offset",
|
||||
"support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
|
||||
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
|
||||
|
Loading…
x
Reference in New Issue
Block a user