Skip to content

Commit

Permalink
merge new feature for 2.5
Browse files Browse the repository at this point in the history
  • Loading branch information
supermerill committed May 9, 2024
2 parents c76b6fd + d8932f2 commit fb42e44
Show file tree
Hide file tree
Showing 53 changed files with 2,556 additions and 755 deletions.
5 changes: 5 additions & 0 deletions .github/workflows/ccpp_mac_arm_rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@ jobs:
ref: 'rc'
- name: build deps & slicer
run: ./BuildMacOS.sh -ia
- name: Upload artifact
uses: actions/[email protected]
with:
name: rc_arm_macos.dmg
path: build/${{ github.event.repository.name }}.dmg
- name: Upload artifact
uses: actions/[email protected]
with:
Expand Down
2 changes: 0 additions & 2 deletions .github/workflows/ccpp_win_rc.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ on:
- rc

jobs:
build_dep:
runs-on: windows-2019

build:
runs-on: windows-2019
Expand Down
1 change: 1 addition & 0 deletions resources/ui_layout/default/extruder.ui
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ group:Offsets (for multi-extruder printers)
setting:idx:extruder_offset
setting:idx:extruder_temperature_offset
setting:idx:extruder_fan_offset
extruder_extrusion_multiplier_speed
group:Retraction
setting:idx:retract_length
setting:idx:retract_lift
Expand Down
18 changes: 16 additions & 2 deletions resources/ui_layout/default/print.ui
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
page:Perimeters & Shell:shell
group:Vertical shells
setting:width$6:perimeters
setting:width$6:perimeters_hole
setting:tags$Simple$Expert$SuSi:script:float:depends$perimeter_spacing$external_perimeter_spacing:label$Wall Thickness:tooltip$Change the perimeter extrusion widths to ensure that there is an exact number of perimeters for this wall thickness value. It won't put the perimeter width below the nozzle diameter, and up to double.\nNote that the value displayed is just a view of the current perimeter thickness, like the info text below. The number of perimeters used to compute this value is one loop, or the custom variable 'wall_thickness_lines' (advanced mode) if defined.\nIf the value is too low, it will revert the widths to the saved value.\nIf the value is set to 0, it will show 0.:s_wall_thickness
setting:spiral_vase
recommended_thin_wall_thickness_description
Expand Down Expand Up @@ -134,6 +135,7 @@ group:Filtering
setting:resolution_internal
setting:model_precision
setting:slice_closing_radius
setting:bridge_precision
# gcode_resolution
group:Modifying slices
line:Curve smoothing
Expand All @@ -159,6 +161,11 @@ group:Modifying slices
setting:sidetext_width$5:hole_to_polyhole_threshold
setting:hole_to_polyhole_twisted
end_line
line:Overhangs cut
setting:overhangs_max_slope
setting:overhangs_bridge_threshold
setting:overhangs_bridge_upper_layers
end_line
group:Other
setting:slicing_mode
setting:clip_multipart_objects
Expand Down Expand Up @@ -211,7 +218,11 @@ group:sidetext_width$5:Infill angle
# setting:fill_angle_template
group:sidetext_width$5:Advanced
setting:solid_infill_every_layers
setting:solid_infill_below_area
line:Solid infill is area below
setting:label$From region:solid_infill_below_area
setting:label$From the whole layer:solid_infill_below_layer_area
end_line
setting:solid_infill_below_width
line:Anchor solid infill by X mm
setting:label_width$8:width$5:external_infill_margin
setting:label_width$6:width$5:bridged_infill_margin
Expand Down Expand Up @@ -444,7 +455,10 @@ group:Overlap
setting:label_width$7:label$External:external_perimeter_overlap
setting:label_width$7:label$Gap Fill:gap_fill_overlap
end_line
setting:width$4:solid_infill_overlap
line:Solid infill ovelrap
setting:label$Inside:width$4:solid_infill_overlap
setting:label$Top:width$4:top_solid_infill_overlap
end_line
line:Bridge lines density
setting:label_width$7:bridge_overlap_min
setting:label_width$7:bridge_overlap
Expand Down
3 changes: 3 additions & 0 deletions src/libslic3r/AppConfig.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -476,6 +476,9 @@ void AppConfig::set_defaults()
if (get("show_layer_time_doubleslider").empty())
set("show_layer_time_doubleslider", "0");

if (get("show_layer_area_doubleslider").empty())
set("show_layer_area_doubleslider", "0");

} else {
#ifdef _WIN32
if (get("associate_gcode").empty())
Expand Down
437 changes: 225 additions & 212 deletions src/libslic3r/BridgeDetector.cpp

Large diffs are not rendered by default.

19 changes: 15 additions & 4 deletions src/libslic3r/BridgeDetector.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,24 @@ class BridgeDetector {
// Lower slices, all regions.
const ExPolygons &lower_slices;
// Scaled extrusion width of the infill.
coord_t spacing;
const coord_t spacing;
// precision, number of lines to use.
const coord_t precision;
// Angle resolution for the brute force search of the best bridging angle.
double resolution;
// The final optimal angle.
double angle;
// ignore bridges that are longer than that.
coordf_t max_bridge_length;


int layer_id = -1;

BridgeDetector(ExPolygon _expolygon, const ExPolygons &_lower_slices, coord_t _extrusion_width);
BridgeDetector(const ExPolygons &_expolygons, const ExPolygons &_lower_slices, coord_t _extrusion_width);
BridgeDetector(ExPolygon _expolygon, const ExPolygons &_lower_slices, coord_t _extrusion_spacing, coord_t _precision, int layer_id);
BridgeDetector(const ExPolygons &_expolygons, const ExPolygons &_lower_slices, coord_t _extrusion_spacing, coord_t _precision, int layer_id);
// If bridge_direction_override != 0, then the angle is used instead of auto-detect.
bool detect_angle(double bridge_direction_override = 0.);
Polygons coverage(double angle = -1, bool precise = true) const;
Polygons coverage(double angle = -1) const;
void unsupported_edges(double angle, Polylines* unsupported) const;
Polylines unsupported_edges(double angle = -1) const;

Expand All @@ -52,9 +59,13 @@ class BridgeDetector {
coordf_t total_length_anchored = 0;
coordf_t median_length_anchor = 0;
coordf_t max_length_anchored = 0;
// number of lines that are anchored at both ends, ie a real bridge
uint32_t nb_lines_anchored = 0;
// number of lines that are anchored but never go in an unsupported area (useless bridge, that can create problems with flow)
uint32_t nb_lines_fake_bridge = 0;
coordf_t total_length_free = 0;
coordf_t max_length_free = 0;
// number of lines that overhangs or floating in the air
uint32_t nb_lines_free = 0;
};
public:
Expand Down
2 changes: 2 additions & 0 deletions src/libslic3r/ClipperUtils.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1169,6 +1169,8 @@ Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygo
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::PolygonsProvider(clip)); }
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::ExPolygon &clip)
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::ExPolygonProvider(clip)); }
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::Polygon &clip)
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::SinglePathProvider(clip.points)); }
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip)
{ return _clipper_pl_open(ClipperLib::ctDifference, ClipperUtils::PolylinesProvider(subject), ClipperUtils::ExPolygonProvider(clip)); }
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip)
Expand Down
1 change: 1 addition & 0 deletions src/libslic3r/ClipperUtils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -419,6 +419,7 @@ Slic3r::ExPolygons diff_ex(const Slic3r::Surfaces &subject, const Slic3r::Surfac
Slic3r::ExPolygons diff_ex(const Slic3r::SurfacesPtr &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No);
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::Polygons &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::ExPolygon &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polyline &subject, const Slic3r::Polygon &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygon &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polylines &subject, const Slic3r::ExPolygons &clip);
Slic3r::Polylines diff_pl(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip);
Expand Down
12 changes: 11 additions & 1 deletion src/libslic3r/Config.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,7 @@ class ConfigOption {
virtual void set(const ConfigOption *option) = 0;
virtual int32_t get_int(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_int on a non-int ConfigOption"); }
virtual double get_float(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_float on a non-float ConfigOption"); }
virtual bool is_percent(size_t idx = 0) const { return false; }
virtual bool get_bool(size_t idx = 0) const { throw BadOptionTypeException("Calling ConfigOption::get_bool on a non-boolean ConfigOption"); }
virtual void set_enum_int(int32_t /* val */) { throw BadOptionTypeException("Calling ConfigOption::set_enum_int on a non-enum ConfigOption"); }
virtual boost::any get_any(int32_t idx = -1) const { throw BadOptionTypeException("Calling ConfigOption::get_any on a raw ConfigOption"); }
Expand Down Expand Up @@ -1159,8 +1160,9 @@ class ConfigOptionPercent : public ConfigOptionFloat
ConfigOptionPercent& operator= (const ConfigOption *opt) { this->set(opt); return *this; }
bool operator==(const ConfigOptionPercent &rhs) const throw() { return this->value == rhs.value; }
bool operator< (const ConfigOptionPercent &rhs) const throw() { return this->value < rhs.value; }

double get_abs_value(double ratio_over) const { return ratio_over * this->value / 100.; }
bool is_percent(size_t idx = 0) const override { return true; }

std::string serialize() const override
{
Expand Down Expand Up @@ -1203,6 +1205,7 @@ class ConfigOptionPercentsTempl : public ConfigOptionFloatsTempl<NULLABLE>
bool operator==(const ConfigOptionPercentsTempl &rhs) const throw() { return ConfigOptionFloatsTempl<NULLABLE>::vectors_equal(this->values, rhs.values); }
bool operator< (const ConfigOptionPercentsTempl &rhs) const throw() { return ConfigOptionFloatsTempl<NULLABLE>::vectors_lower(this->values, rhs.values); }
double get_abs_value(size_t i, double ratio_over) const { return this->is_nil(i) ? 0 : ratio_over * this->get_at(i) / 100; }
bool is_percent(size_t idx = 0) const override { return true; }

std::string serialize() const override
{
Expand Down Expand Up @@ -1272,6 +1275,7 @@ class ConfigOptionFloatOrPercent : public ConfigOptionPercent
double get_abs_value(double ratio_over) const
{ return this->percent ? (ratio_over * this->value / 100) : this->value; }
double get_float(size_t idx = 0) const override { return get_abs_value(1.); }
bool is_percent(size_t idx = 0) const override { return this->percent; }
// special case for get/set any: use a FloatOrPercent like for FloatsOrPercents, to have the is_percent
boost::any get_any(int32_t idx = 0) const override { return boost::any(FloatOrPercent{value, percent}); }
void set_any(boost::any anyval, int32_t idx = -1) override
Expand Down Expand Up @@ -1357,6 +1361,12 @@ class ConfigOptionFloatsOrPercentsTempl : public ConfigOptionVector<FloatOrPerce
return data.value;
}
double get_float(size_t idx = 0) const override { return get_abs_value(idx, 1.); }
bool is_percent(size_t idx = 0) const override
{
if (this->is_nil(idx))
return false;
return this->get_at(idx).percent;
}

static inline bool is_nil(const boost::any &to_check) {
bool ok = std::isnan(boost::any_cast<FloatOrPercent>(to_check).value) || boost::any_cast<FloatOrPercent>(to_check).value == NIL_VALUE().value
Expand Down
26 changes: 24 additions & 2 deletions src/libslic3r/ExPolygon.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -221,6 +221,8 @@ inline Polylines to_polylines(ExPolygons &&src)

inline Polygons to_polygons(const ExPolygon &src)
{
assert(src.contour.is_counter_clockwise());
assert(src.holes.empty() || src.holes.front().is_clockwise());
Polygons polygons;
polygons.reserve(src.holes.size() + 1);
polygons.push_back(src.contour);
Expand All @@ -233,6 +235,8 @@ inline Polygons to_polygons(const ExPolygons &src)
Polygons polygons;
polygons.reserve(number_polygons(src));
for (const ExPolygon& ex_poly : src) {
assert(ex_poly.contour.is_counter_clockwise());
assert(ex_poly.holes.empty() || ex_poly.holes.front().is_clockwise());
polygons.push_back(ex_poly.contour);
polygons.insert(polygons.end(), ex_poly.holes.begin(), ex_poly.holes.end());
}
Expand All @@ -241,6 +245,8 @@ inline Polygons to_polygons(const ExPolygons &src)

inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygon &src)
{
assert(src.contour.is_counter_clockwise());
assert(src.holes.empty() || src.holes.front().is_clockwise());
ConstPolygonPtrs polygons;
polygons.reserve(src.holes.size() + 1);
polygons.emplace_back(&src.contour);
Expand All @@ -254,6 +260,8 @@ inline ConstPolygonPtrs to_polygon_ptrs(const ExPolygons &src)
ConstPolygonPtrs polygons;
polygons.reserve(number_polygons(src));
for (const ExPolygon &expoly : src) {
assert(expoly.contour.is_counter_clockwise());
assert(expoly.holes.empty() || expoly.holes.front().is_clockwise());
polygons.emplace_back(&expoly.contour);
for (const Polygon &hole : expoly.holes)
polygons.emplace_back(&hole);
Expand All @@ -276,6 +284,8 @@ inline Polygons to_polygons(ExPolygons &&src)
Polygons polygons;
polygons.reserve(number_polygons(src));
for (ExPolygons::iterator it = src.begin(); it != src.end(); ++it) {
assert(it->contour.is_counter_clockwise());
assert(it->holes.empty() || it->holes.front().is_clockwise());
polygons.push_back(std::move(it->contour));
std::move(std::begin(it->holes), std::end(it->holes), std::back_inserter(polygons));
it->holes.clear();
Expand All @@ -287,22 +297,28 @@ inline ExPolygons to_expolygons(const Polygons &polys)
{
ExPolygons ex_polys;
ex_polys.assign(polys.size(), ExPolygon());
for (size_t idx = 0; idx < polys.size(); ++idx)
for (size_t idx = 0; idx < polys.size(); ++idx) {
assert(polys[idx].is_counter_clockwise());
ex_polys[idx].contour = polys[idx];
}
return ex_polys;
}

inline ExPolygons to_expolygons(Polygons &&polys)
{
ExPolygons ex_polys;
ex_polys.assign(polys.size(), ExPolygon());
for (size_t idx = 0; idx < polys.size(); ++idx)
for (size_t idx = 0; idx < polys.size(); ++idx) {
assert(polys[idx].is_counter_clockwise());
ex_polys[idx].contour = std::move(polys[idx]);
}
return ex_polys;
}

inline void polygons_append(Polygons &dst, const ExPolygon &src)
{
assert(src.contour.is_counter_clockwise());
assert(src.holes.empty() || src.holes.front().is_clockwise());
dst.reserve(dst.size() + src.holes.size() + 1);
dst.push_back(src.contour);
dst.insert(dst.end(), src.holes.begin(), src.holes.end());
Expand All @@ -312,13 +328,17 @@ inline void polygons_append(Polygons &dst, const ExPolygons &src)
{
dst.reserve(dst.size() + number_polygons(src));
for (ExPolygons::const_iterator it = src.begin(); it != src.end(); ++ it) {
assert(it->contour.is_counter_clockwise());
assert(it->holes.empty() || it->holes.front().is_clockwise());
dst.push_back(it->contour);
dst.insert(dst.end(), it->holes.begin(), it->holes.end());
}
}

inline void polygons_append(Polygons &dst, ExPolygon &&src)
{
assert(src.contour.is_counter_clockwise());
assert(src.holes.empty() || src.holes.front().is_clockwise());
dst.reserve(dst.size() + src.holes.size() + 1);
dst.push_back(std::move(src.contour));
std::move(std::begin(src.holes), std::end(src.holes), std::back_inserter(dst));
Expand All @@ -329,6 +349,8 @@ inline void polygons_append(Polygons &dst, ExPolygons &&src)
{
dst.reserve(dst.size() + number_polygons(src));
for (ExPolygons::iterator it = src.begin(); it != src.end(); ++ it) {
assert(it->contour.is_counter_clockwise());
assert(it->holes.empty() || it->holes.front().is_clockwise());
dst.push_back(std::move(it->contour));
std::move(std::begin(it->holes), std::end(it->holes), std::back_inserter(dst));
it->holes.clear();
Expand Down
46 changes: 43 additions & 3 deletions src/libslic3r/ExtrusionEntityCollection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,49 @@ void ExtrusionEntityCollection::remove(size_t i)

void ExtrusionEntityCollection::chained_path_from(const Point &start_near)
{
if (this->m_no_sort)
return;
chain_and_reorder_extrusion_entities(this->m_entities, &start_near);
if (this->m_no_sort) {
if (this->m_can_reverse) {
if (m_entities.size() > 1) {
//can't sort myself, ask first and last thign to sort itself so the first point of each are the best ones
if (m_entities.front()->is_collection()) {
assert(dynamic_cast<ExtrusionEntityCollection*>(m_entities.front()) != nullptr);
static_cast<ExtrusionEntityCollection*>(m_entities.front())->chained_path_from(start_near);
} else if (m_entities.front()->can_reverse() &&
m_entities.front()->first_point().distance_to_square(start_near) >
m_entities.front()->first_point().distance_to_square(start_near)) {
m_entities.front()->reverse();
}
if (m_entities.back()->is_collection()) {
assert(dynamic_cast<ExtrusionEntityCollection*>(m_entities.front()) != nullptr);
static_cast<ExtrusionEntityCollection*>(m_entities.back())->chained_path_from(start_near);
} else if (m_entities.back()->can_reverse() &&
m_entities.back()->first_point().distance_to_square(start_near) >
m_entities.back()->first_point().distance_to_square(start_near)) {
m_entities.back()->reverse();
}
//now check if it's better for us to reverse
if (start_near.distance_to_square(this->m_entities.front()->first_point()) >
start_near.distance_to_square(this->m_entities.back()->first_point())) {
// switch entities
this->reverse();
}
}
// now we are in our good order, update the internals
Point last_point = start_near;
for (ExtrusionEntity *entity : m_entities) {
if (entity->is_collection()) {
assert(dynamic_cast<ExtrusionEntityCollection*>(entity) != nullptr);
static_cast<ExtrusionEntityCollection*>(entity)->chained_path_from(last_point);
} else if (entity->can_reverse() && entity->first_point().distance_to_square(last_point) >
entity->first_point().distance_to_square(last_point)) {
entity->reverse();
}
last_point = entity->last_point();
}
}
} else {
chain_and_reorder_extrusion_entities(this->m_entities, &start_near);
}
}

void ExtrusionEntityCollection::polygons_covered_by_width(Polygons &out, const float scaled_epsilon) const
Expand Down
Loading

0 comments on commit fb42e44

Please sign in to comment.