Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/supermerill/SuperSlicer.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorsupermerill <merill@fr.fr>2019-01-09 22:49:58 +0300
committersupermerill <merill@fr.fr>2019-01-11 01:49:06 +0300
commitb1b76c07235dbe55ea6f350c17e1e8143fb08643 (patch)
treef3ca91ffe6ad03c17868ffa0e443064f57c37c14
parentb91b4760329f3b2851e1be44c6297c465a01f35b (diff)
- add brim_ears setting: bool: set to true to activate this new funtino - add brim_ears_max_angle : float : max angle for a corner to be assigned a brim ear.
-rw-r--r--src/libslic3r/GCode.cpp2
-rw-r--r--src/libslic3r/Print.cpp178
-rw-r--r--src/libslic3r/Print.hpp1
-rw-r--r--src/libslic3r/PrintConfig.cpp15
-rw-r--r--src/libslic3r/PrintConfig.hpp4
-rw-r--r--src/slic3r/GUI/Preset.cpp3
-rw-r--r--src/slic3r/GUI/Tab.cpp9
7 files changed, 202 insertions, 10 deletions
diff --git a/src/libslic3r/GCode.cpp b/src/libslic3r/GCode.cpp
index b32190084..256a03862 100644
--- a/src/libslic3r/GCode.cpp
+++ b/src/libslic3r/GCode.cpp
@@ -1567,7 +1567,7 @@ void GCode::process_layer(
this->set_origin(0., 0.);
m_avoid_crossing_perimeters.use_external_mp = true;
for (const ExtrusionEntity *ee : print.brim().entities)
- gcode += this->extrude_loop(*dynamic_cast<const ExtrusionLoop*>(ee), "brim", m_config.support_material_speed.value);
+ gcode += this->extrude_entity(*ee, "brim", m_config.support_material_speed.value);
m_brim_done = true;
m_avoid_crossing_perimeters.use_external_mp = false;
// Allow a straight travel move to the first object point.
diff --git a/src/libslic3r/Print.cpp b/src/libslic3r/Print.cpp
index 407ad5625..a4034981b 100644
--- a/src/libslic3r/Print.cpp
+++ b/src/libslic3r/Print.cpp
@@ -195,7 +195,9 @@ bool Print::invalidate_state_by_config_options(const std::vector<t_config_option
|| opt_key == "min_skirt_length"
|| opt_key == "ooze_prevention") {
steps.emplace_back(psSkirt);
- } else if (opt_key == "brim_width") {
+ } else if (opt_key == "brim_width"
+ || opt_key == "brim_ears"
+ || opt_key == "brim_ears_max_angle") {
steps.emplace_back(psBrim);
steps.emplace_back(psSkirt);
} else if (
@@ -1499,7 +1501,10 @@ void Print::process()
m_brim.clear();
if (m_config.brim_width > 0) {
this->set_status(88, "Generating brim");
- this->_make_brim();
+ if (config().brim_ears)
+ this->_make_brim_ears();
+ else
+ this->_make_brim();
}
this->set_done(psBrim);
}
@@ -1673,8 +1678,7 @@ void Print::_make_skirt()
m_skirt.reverse();
}
-void Print::_make_brim()
-{
+void Print::_make_brim() {
// Brim is only printed on first layer and uses perimeter extruder.
Flow flow = this->brim_flow();
Polygons islands;
@@ -1682,7 +1686,7 @@ void Print::_make_brim()
Polygons object_islands;
for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
object_islands.push_back(expoly.contour);
- if (! object->support_layers().empty())
+ if (!object->support_layers().empty())
object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
islands.reserve(islands.size() + object_islands.size() * object->m_copies.size());
for (const Point &pt : object->m_copies)
@@ -1693,7 +1697,7 @@ void Print::_make_brim()
}
Polygons loops;
size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
- for (size_t i = 0; i < num_loops; ++ i) {
+ for (size_t i = 0; i < num_loops; ++i) {
this->throw_if_canceled();
islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
for (Polygon &poly : islands) {
@@ -1705,12 +1709,172 @@ void Print::_make_brim()
}
polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
}
-
+
loops = union_pt_chained(loops, false);
std::reverse(loops.begin(), loops.end());
extrusion_entities_append_loops(m_brim.entities, std::move(loops), erSkirt, float(flow.mm3_per_mm()), float(flow.width), float(this->skirt_first_layer_height()));
}
+void Print::_make_brim_ears() {
+ Flow flow = this->brim_flow();
+ Points pt_ears;
+ Polygons islands;
+ for (PrintObject *object : m_objects) {
+ Polygons object_islands;
+ for (ExPolygon &expoly : object->m_layers.front()->slices.expolygons)
+ object_islands.push_back(expoly.contour);
+ if (!object->support_layers().empty())
+ object->support_layers().front()->support_fills.polygons_covered_by_spacing(object_islands, float(SCALED_EPSILON));
+ islands.reserve(islands.size() + object_islands.size() * object->m_copies.size());
+ for (const Point &copy_pt : object->m_copies)
+ for (const Polygon &poly : object_islands) {
+ islands.push_back(poly);
+ islands.back().translate(copy_pt);
+ for (const Point &p : poly.convex_points(config().brim_ears_max_angle.value * PI / 180.0)) {
+ pt_ears.push_back(p);
+ pt_ears.back() += (copy_pt);
+ }
+ }
+ }
+
+ //create loops (same as standard brim)
+ Polygons loops;
+ size_t num_loops = size_t(floor(m_config.brim_width.value / flow.spacing()));
+ for (size_t i = 0; i < num_loops; ++i) {
+ this->throw_if_canceled();
+ islands = offset(islands, float(flow.scaled_spacing()), jtSquare);
+ for (Polygon &poly : islands) {
+ // poly.simplify(SCALED_RESOLUTION);
+ poly.points.push_back(poly.points.front());
+ Points p = MultiPoint::_douglas_peucker(poly.points, SCALED_RESOLUTION);
+ p.pop_back();
+ poly.points = std::move(p);
+ }
+ polygons_append(loops, offset(islands, -0.5f * float(flow.scaled_spacing())));
+ }
+ loops = union_pt_chained(loops, false);
+
+
+ //create ear pattern
+ coord_t size_ear = (scale_(m_config.brim_width.value) - flow.scaled_spacing());
+ Polygon point_round;
+ point_round.points.push_back(Point(size_ear * 1, 0 * size_ear));
+ point_round.points.push_back(Point(size_ear*0.966, 0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*0.87, 0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*0.7, 0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*0.5, 0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*0.26, 0.966*size_ear));
+ point_round.points.push_back(Point(size_ear * 0, 1 * size_ear));
+ point_round.points.push_back(Point(size_ear*-0.26, 0.966*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.5, 0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.7, 0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.87, 0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.966, 0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*-1, 0 * size_ear));
+ point_round.points.push_back(Point(size_ear*-0.966, -0.26*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.87, -0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.7, -0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.5, -0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*-0.26, -0.966*size_ear));
+ point_round.points.push_back(Point(size_ear * 0, -1 * size_ear));
+ point_round.points.push_back(Point(size_ear*0.26, -0.966*size_ear));
+ point_round.points.push_back(Point(size_ear*0.5, -0.87*size_ear));
+ point_round.points.push_back(Point(size_ear*0.7, -0.7*size_ear));
+ point_round.points.push_back(Point(size_ear*0.87, -0.5*size_ear));
+ point_round.points.push_back(Point(size_ear*0.966, -0.26*size_ear));
+
+ //create ears
+ Polygons mouse_ears;
+ for (Point pt : pt_ears) {
+ mouse_ears.push_back(point_round);
+ mouse_ears.back().translate(pt);
+ }
+
+ //intersection
+ Polylines lines = intersection_pl(loops, mouse_ears);
+
+ //reorder them
+ std::sort(lines.begin(), lines.end(), [](const Polyline &a, const Polyline &b)->bool { return a.closest_point(Point(0, 0))->y() < b.closest_point(Point(0, 0))->y(); });
+ Polylines lines_sorted;
+ Polyline* previous = NULL;
+ Polyline* best = NULL;
+ double best_dist = -1;
+ size_t best_idx = 0;
+ while (lines.size() > 0) {
+ if (previous == NULL) {
+ lines_sorted.push_back(lines.back());
+ previous = &lines_sorted.back();
+ lines.erase(lines.end() - 1);
+ } else {
+ best = NULL;
+ best_dist = -1;
+ best_idx = 0;
+ for (size_t i = 0; i < lines.size(); ++i) {
+ Polyline &viewed_line = lines[i];
+ double dist = viewed_line.points.front().distance_to(previous->points.front());
+ dist = std::min(dist, viewed_line.points.front().distance_to(previous->points.back()));
+ dist = std::min(dist, viewed_line.points.back().distance_to(previous->points.front()));
+ dist = std::min(dist, viewed_line.points.back().distance_to(previous->points.back()));
+ if (dist < best_dist || best == NULL) {
+ best = &viewed_line;
+ best_dist = dist;
+ best_idx = i;
+ }
+ }
+ if (best != NULL) {
+ //copy new line inside the sorted array.
+ lines_sorted.push_back(lines[best_idx]);
+ lines.erase(lines.begin() + best_idx);
+
+ //connect if near enough
+ if (lines_sorted.size() > 1) {
+ size_t idx = lines_sorted.size() - 2;
+ bool connect = false;
+ if (lines_sorted[idx].points.back().distance_to(lines_sorted[idx + 1].points.front()) < flow.scaled_spacing() * 2) {
+ connect = true;
+ } else if (lines_sorted[idx].points.back().distance_to(lines_sorted[idx + 1].points.back()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx + 1].reverse();
+ connect = true;
+ } else if (lines_sorted[idx].points.front().distance_to(lines_sorted[idx + 1].points.front()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx].reverse();
+ connect = true;
+ } else if (lines_sorted[idx].points.front().distance_to(lines_sorted[idx + 1].points.back()) < flow.scaled_spacing() * 2) {
+ lines_sorted[idx].reverse();
+ lines_sorted[idx + 1].reverse();
+ connect = true;
+ }
+
+ if (connect) {
+ //connect them
+ lines_sorted[idx].points.insert(
+ lines_sorted[idx].points.end(),
+ lines_sorted[idx + 1].points.begin(),
+ lines_sorted[idx + 1].points.end());
+ lines_sorted.erase(lines_sorted.begin() + idx + 1);
+ idx--;
+ }
+ }
+
+ //update last position
+ previous = &lines_sorted.back();
+ } else {
+ previous == NULL;
+ }
+
+ }
+ }
+
+ //push into extrusions
+ extrusion_entities_append_paths(
+ m_brim.entities,
+ lines_sorted,
+ erSkirt,
+ float(flow.mm3_per_mm()),
+ float(flow.width),
+ float(this->skirt_first_layer_height())
+ );
+}
+
// Wipe tower support.
bool Print::has_wipe_tower() const
{
diff --git a/src/libslic3r/Print.hpp b/src/libslic3r/Print.hpp
index de3215578..b68fb1518 100644
--- a/src/libslic3r/Print.hpp
+++ b/src/libslic3r/Print.hpp
@@ -374,6 +374,7 @@ private:
void _make_skirt();
void _make_brim();
+ void _make_brim_ears();
void _make_wipe_tower();
void _simplify_slices(double distance);
diff --git a/src/libslic3r/PrintConfig.cpp b/src/libslic3r/PrintConfig.cpp
index f0d62bb88..3b55e7ab3 100644
--- a/src/libslic3r/PrintConfig.cpp
+++ b/src/libslic3r/PrintConfig.cpp
@@ -212,6 +212,21 @@ void PrintConfigDef::init_fff_params()
def->min = 0;
def->default_value = new ConfigOptionFloat(0);
+ def = this->add("brim_ears", coBool);
+ def->label = L(" ");
+ def->tooltip = L("Only draw brim over the sharp edges of the model.");
+ def->cli = "brim-ears!";
+ def->default_value = new ConfigOptionBool(false);
+
+ def = this->add("brim_ears_max_angle", coFloat);
+ def->label = L("max angle");
+ def->tooltip = L("Maximum angle to let a brim ear appear.");
+ def->sidetext = L("°");
+ def->cli = "brim-ears-max-angle=f";
+ def->min = 0;
+ def->max = 180;
+ def->default_value = new ConfigOptionFloat(125);
+
def = this->add("clip_multipart_objects", coBool);
def->label = L("Clip multi-part objects");
def->tooltip = L("When printing multi-material objects, this settings will make slic3r "
diff --git a/src/libslic3r/PrintConfig.hpp b/src/libslic3r/PrintConfig.hpp
index b5b290d39..be1bc9f1f 100644
--- a/src/libslic3r/PrintConfig.hpp
+++ b/src/libslic3r/PrintConfig.hpp
@@ -788,6 +788,8 @@ public:
ConfigOptionInts bridge_fan_speed;
ConfigOptionInts top_fan_speed;
ConfigOptionFloat brim_width;
+ ConfigOptionBool brim_ears;
+ ConfigOptionFloat brim_ears_max_angle;
ConfigOptionBool complete_objects;
ConfigOptionFloats colorprint_heights;
ConfigOptionBools cooling;
@@ -867,6 +869,8 @@ protected:
OPT_PTR(bridge_fan_speed);
OPT_PTR(top_fan_speed);
OPT_PTR(brim_width);
+ OPT_PTR(brim_ears);
+ OPT_PTR(brim_ears_max_angle);
OPT_PTR(complete_objects);
OPT_PTR(colorprint_heights);
OPT_PTR(cooling);
diff --git a/src/slic3r/GUI/Preset.cpp b/src/slic3r/GUI/Preset.cpp
index 876bb3b45..84fae86b3 100644
--- a/src/slic3r/GUI/Preset.cpp
+++ b/src/slic3r/GUI/Preset.cpp
@@ -328,7 +328,8 @@ const std::vector<std::string>& Preset::print_options()
"top_solid_infill_speed", "support_material_speed", "support_material_xy_spacing", "support_material_interface_speed",
"bridge_speed", "gap_fill", "gap_fill_speed", "travel_speed", "first_layer_speed", "perimeter_acceleration", "infill_acceleration",
"bridge_acceleration", "first_layer_acceleration", "default_acceleration", "skirts", "skirt_distance", "skirt_height",
- "min_skirt_length", "brim_width", "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
+ "min_skirt_length", "brim_width", "brim_ears", "brim_ears_max_angle",
+ "support_material", "support_material_auto", "support_material_threshold", "support_material_enforce_layers",
"raft_layers", "support_material_pattern", "support_material_with_sheath", "support_material_spacing",
"support_material_synchronize_layers", "support_material_angle", "support_material_interface_layers",
"support_material_interface_spacing", "support_material_interface_contact_loops", "support_material_contact_distance",
diff --git a/src/slic3r/GUI/Tab.cpp b/src/slic3r/GUI/Tab.cpp
index 83f7e1e73..fa67a9b61 100644
--- a/src/slic3r/GUI/Tab.cpp
+++ b/src/slic3r/GUI/Tab.cpp
@@ -988,7 +988,11 @@ void TabPrint::build()
optgroup->append_single_option_line("min_skirt_length");
optgroup = page->new_optgroup(_(L("Brim")));
- optgroup->append_single_option_line("brim_width");
+ optgroup->append_single_option_line("brim_width");
+ line = { _(L("Brim ears")), "" };
+ line.append_option(optgroup->get_option("brim_ears"));
+ line.append_option(optgroup->get_option("brim_ears_max_angle"));
+ optgroup->append_line(line);
page = add_options_page(_(L("Support material")), "building.png");
optgroup = page->new_optgroup(_(L("Support material")));
@@ -1379,6 +1383,9 @@ void TabPrint::update()
// perimeter_extruder uses the same logic as in Print::extruders()
get_field("perimeter_extruder")->toggle(have_perimeters || have_brim);
+ get_field("brim_ears")->toggle(have_brim);
+ get_field("brim_ears_max_angle")->toggle(have_brim && m_config->opt_bool("brim_ears"));
+
bool have_raft = m_config->opt_int("raft_layers") > 0;
bool have_support_material = m_config->opt_bool("support_material") || have_raft;
bool have_support_material_auto = have_support_material && m_config->opt_bool("support_material_auto");