From f494ad565ba7140281274e3a6955d24cffe8bc97 Mon Sep 17 00:00:00 2001 From: tamasmeszaros Date: Mon, 18 Oct 2021 14:38:19 +0200 Subject: [PATCH 01/18] Fix some builds that fail with cgal 5.2.3 --- src/libslic3r/MeshBoolean.cpp | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/MeshBoolean.cpp b/src/libslic3r/MeshBoolean.cpp index e2e5e254a..95daa33a6 100644 --- a/src/libslic3r/MeshBoolean.cpp +++ b/src/libslic3r/MeshBoolean.cpp @@ -159,8 +159,9 @@ template TriangleMesh cgal_to_triangle_mesh(const _Mesh &cgalmesh) int i = 0; Vec3i facet; for (auto v : vtc) { - if (i > 2 || v < 0 || v >= cgalmesh.vertices().size()) { i = 0; break; } - facet(i++) = v; + int iv = v; + if (i > 2 || iv < 0 || iv >= int(cgalmesh.vertices().size())) { i = 0; break; } + facet(i++) = iv; } if (i == 3) From 556e0c53c7a026a9a701a302d179764f0be2c41b Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 18 Oct 2021 14:51:09 +0200 Subject: [PATCH 02/18] Some more refactoring of ClipperLib / closing() / opening() --- src/libslic3r/Brim.cpp | 2 +- src/libslic3r/ClipperUtils.cpp | 27 +++++++++++++++++++++++++++ src/libslic3r/ClipperUtils.hpp | 27 ++++++++++++++++++++++----- src/libslic3r/LayerRegion.cpp | 5 ++--- src/libslic3r/PrintObject.cpp | 4 ++-- 5 files changed, 54 insertions(+), 11 deletions(-) diff --git a/src/libslic3r/Brim.cpp b/src/libslic3r/Brim.cpp index 69a9e87f9..a13d578a3 100644 --- a/src/libslic3r/Brim.cpp +++ b/src/libslic3r/Brim.cpp @@ -50,7 +50,7 @@ static ExPolygons get_print_object_bottom_layer_expolygons(const PrintObject &pr { ExPolygons ex_polygons; for (LayerRegion *region : print_object.layers().front()->regions()) - Slic3r::append(ex_polygons, offset_ex(offset_ex(region->slices.surfaces, float(SCALED_EPSILON)), -float(SCALED_EPSILON))); + Slic3r::append(ex_polygons, closing_ex(region->slices.surfaces, float(SCALED_EPSILON))); return ex_polygons; } diff --git a/src/libslic3r/ClipperUtils.cpp b/src/libslic3r/ClipperUtils.cpp index 9b95bfed6..28fb09313 100644 --- a/src/libslic3r/ClipperUtils.cpp +++ b/src/libslic3r/ClipperUtils.cpp @@ -452,6 +452,11 @@ ExPolygons offset2_ex(const ExPolygons &expolygons, const float delta1, const fl { return PolyTreeToExPolygons(offset_paths(expolygons_offset(expolygons, delta1, joinType, miterLimit), delta2, joinType, miterLimit)); } +ExPolygons offset2_ex(const Surfaces &surfaces, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) +{ + //FIXME it may be more efficient to offset to_expolygons(surfaces) instead of to_polygons(surfaces). + return PolyTreeToExPolygons(offset_paths(expolygons_offset(surfaces, delta1, joinType, miterLimit), delta2, joinType, miterLimit)); +} // Offset outside, then inside produces morphological closing. All deltas should be positive. Slic3r::Polygons closing(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) @@ -466,6 +471,13 @@ Slic3r::ExPolygons closing_ex(const Slic3r::Polygons &polygons, const float delt assert(delta2 > 0); return PolyTreeToExPolygons(shrink_paths(expand_paths(ClipperUtils::PolygonsProvider(polygons), delta1, joinType, miterLimit), delta2, joinType, miterLimit)); } +Slic3r::ExPolygons closing_ex(const Slic3r::Surfaces &surfaces, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) +{ + assert(delta1 > 0); + assert(delta2 > 0); + //FIXME it may be more efficient to offset to_expolygons(surfaces) instead of to_polygons(surfaces). + return PolyTreeToExPolygons(shrink_paths(expand_paths(ClipperUtils::SurfacesProvider(surfaces), delta1, joinType, miterLimit), delta2, joinType, miterLimit)); +} // Offset inside, then outside produces morphological opening. All deltas should be positive. Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) @@ -474,6 +486,19 @@ Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta1, c assert(delta2 > 0); return to_polygons(expand_paths(shrink_paths(ClipperUtils::PolygonsProvider(polygons), delta1, joinType, miterLimit), delta2, joinType, miterLimit)); } +Slic3r::Polygons opening(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) +{ + assert(delta1 > 0); + assert(delta2 > 0); + return to_polygons(expand_paths(shrink_paths(ClipperUtils::ExPolygonsProvider(expolygons), delta1, joinType, miterLimit), delta2, joinType, miterLimit)); +} +Slic3r::Polygons opening(const Slic3r::Surfaces &surfaces, const float delta1, const float delta2, ClipperLib::JoinType joinType, double miterLimit) +{ + assert(delta1 > 0); + assert(delta2 > 0); + //FIXME it may be more efficient to offset to_expolygons(surfaces) instead of to_polygons(surfaces). + return to_polygons(expand_paths(shrink_paths(ClipperUtils::SurfacesProvider(surfaces), delta1, joinType, miterLimit), delta2, joinType, miterLimit)); +} // Fix of #117: A large fractal pyramid takes ages to slice // The Clipper library has difficulties processing overlapping polygons. @@ -525,6 +550,8 @@ Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons { return _clipper(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); } Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset) { return _clipper(ClipperLib::ctDifference, ClipperUtils::ExPolygonsProvider(subject), ClipperUtils::ExPolygonsProvider(clip), do_safety_offset); } +Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) + { return _clipper(ClipperLib::ctDifference, ClipperUtils::SurfacesProvider(subject), ClipperUtils::PolygonsProvider(clip), do_safety_offset); } Slic3r::Polygons intersection(const Slic3r::Polygon &subject, const Slic3r::Polygon &clip, ApplySafetyOffset do_safety_offset) { return _clipper(ClipperLib::ctIntersection, ClipperUtils::SinglePathProvider(subject.points), ClipperUtils::SinglePathProvider(clip.points), do_safety_offset); } Slic3r::Polygons intersection(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset) diff --git a/src/libslic3r/ClipperUtils.hpp b/src/libslic3r/ClipperUtils.hpp index 829611176..bbd91c0fd 100644 --- a/src/libslic3r/ClipperUtils.hpp +++ b/src/libslic3r/ClipperUtils.hpp @@ -345,19 +345,35 @@ inline Slic3r::ExPolygons shrink_ex(const Slic3r::Polygons &polygons, const floa // Input polygons for negative offset shall be "normalized": There must be no overlap / intersections between the input polygons. Slic3r::Polygons offset2(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); Slic3r::ExPolygons offset2_ex(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); +Slic3r::ExPolygons offset2_ex(const Slic3r::Surfaces &surfaces, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); // Offset outside, then inside produces morphological closing. All deltas should be positive. Slic3r::Polygons closing(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); -inline Slic3r::Polygons closing(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) { return closing(polygons, delta, delta, joinType, miterLimit); } +inline Slic3r::Polygons closing(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { return closing(polygons, delta, delta, joinType, miterLimit); } Slic3r::ExPolygons closing_ex(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); -inline Slic3r::ExPolygons closing_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) { return closing_ex(polygons, delta, delta, joinType, miterLimit); } -inline Slic3r::ExPolygons closing_ex(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) { return offset2_ex(polygons, delta, - delta, joinType, miterLimit); } +inline Slic3r::ExPolygons closing_ex(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { return closing_ex(polygons, delta, delta, joinType, miterLimit); } +inline Slic3r::ExPolygons closing_ex(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { assert(delta > 0); return offset2_ex(polygons, delta, - delta, joinType, miterLimit); } +inline Slic3r::ExPolygons closing_ex(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { assert(delta > 0); return offset2_ex(surfaces, delta, - delta, joinType, miterLimit); } // Offset inside, then outside produces morphological opening. All deltas should be positive. // Input polygons for opening shall be "normalized": There must be no overlap / intersections between the input polygons. Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); -inline Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) { return opening(polygons, delta, delta, joinType, miterLimit); } -inline Slic3r::ExPolygons opening_ex(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) { return offset2_ex(polygons, - delta, delta, joinType, miterLimit); } +Slic3r::Polygons opening(const Slic3r::ExPolygons &expolygons, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); +Slic3r::Polygons opening(const Slic3r::Surfaces &surfaces, const float delta1, const float delta2, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit); +inline Slic3r::Polygons opening(const Slic3r::Polygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { return opening(polygons, delta, delta, joinType, miterLimit); } +inline Slic3r::Polygons opening(const Slic3r::ExPolygons &expolygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { return opening(expolygons, delta, delta, joinType, miterLimit); } +inline Slic3r::Polygons opening(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { return opening(surfaces, delta, delta, joinType, miterLimit); } +inline Slic3r::ExPolygons opening_ex(const Slic3r::ExPolygons &polygons, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { assert(delta > 0); return offset2_ex(polygons, - delta, delta, joinType, miterLimit); } +inline Slic3r::ExPolygons opening_ex(const Slic3r::Surfaces &surfaces, const float delta, ClipperLib::JoinType joinType = DefaultJoinType, double miterLimit = DefaultMiterLimit) + { assert(delta > 0); return offset2_ex(surfaces, - delta, delta, joinType, miterLimit); } Slic3r::Lines _clipper_ln(ClipperLib::ClipType clipType, const Slic3r::Lines &subject, const Slic3r::Polygons &clip); @@ -366,6 +382,7 @@ Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::Polygons Slic3r::Polygons diff(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::Polygons diff(const Slic3r::ExPolygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); +Slic3r::Polygons diff(const Slic3r::Surfaces &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Polygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::ExPolygons &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); Slic3r::ExPolygons diff_ex(const Slic3r::Polygons &subject, const Slic3r::Surfaces &clip, ApplySafetyOffset do_safety_offset = ApplySafetyOffset::No); diff --git a/src/libslic3r/LayerRegion.cpp b/src/libslic3r/LayerRegion.cpp index 356811b74..4dbffe7b0 100644 --- a/src/libslic3r/LayerRegion.cpp +++ b/src/libslic3r/LayerRegion.cpp @@ -431,9 +431,8 @@ void LayerRegion::elephant_foot_compensation_step(const float elephant_foot_comp for (const Surface &surface : this->slices.surfaces) assert(surface.surface_type == stInternal); #endif /* NDEBUG */ - ExPolygons surfaces = to_expolygons(std::move(this->slices.surfaces)); - Polygons tmp = intersection(surfaces, trimming_polygons); - append(tmp, diff(surfaces, offset(offset_ex(surfaces, -elephant_foot_compensation_perimeter_step), elephant_foot_compensation_perimeter_step))); + Polygons tmp = intersection(this->slices.surfaces, trimming_polygons); + append(tmp, diff(this->slices.surfaces, opening(this->slices.surfaces, elephant_foot_compensation_perimeter_step))); this->slices.set(union_ex(tmp), stInternal); } diff --git a/src/libslic3r/PrintObject.cpp b/src/libslic3r/PrintObject.cpp index dd5a2b573..fd98feff7 100644 --- a/src/libslic3r/PrintObject.cpp +++ b/src/libslic3r/PrintObject.cpp @@ -1088,7 +1088,7 @@ void PrintObject::discover_vertical_shells() // For a multi-material print, simulate perimeter / infill split as if only a single extruder has been used for the whole print. if (perimeter_offset > 0.) { // The layer.lslices are forced to merge by expanding them first. - polygons_append(cache.holes, offset(offset_ex(layer.lslices, 0.3f * perimeter_min_spacing), - perimeter_offset - 0.3f * perimeter_min_spacing)); + polygons_append(cache.holes, offset2(layer.lslices, 0.3f * perimeter_min_spacing, - perimeter_offset - 0.3f * perimeter_min_spacing)); #ifdef SLIC3R_DEBUG_SLICE_PROCESSING { Slic3r::SVG svg(debug_out_path("discover_vertical_shells-extra-holes-%d.svg", debug_idx), get_extents(layer.lslices)); @@ -1325,7 +1325,7 @@ void PrintObject::discover_vertical_shells() #if 1 // Intentionally inflate a bit more than how much the region has been shrunk, // so there will be some overlap between this solid infill and the other infill regions (mainly the sparse infill). - shell = offset(offset_ex(union_ex(shell), - 0.5f * min_perimeter_infill_spacing), 0.8f * min_perimeter_infill_spacing, ClipperLib::jtSquare); + shell = opening(union_(shell), 0.5f * min_perimeter_infill_spacing, 0.8f * min_perimeter_infill_spacing, ClipperLib::jtSquare); if (shell.empty()) continue; #else From 32ebfa66e936a67160615aec5f2556fc8956a4d7 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 18 Oct 2021 14:56:02 +0200 Subject: [PATCH 03/18] Fix of M106 on every new layer #7094 after parallelization of CoolingBuffer: Remember the last fan speed emitted at the previous layer. --- src/libslic3r/GCode/CoolingBuffer.cpp | 12 ++++++------ src/libslic3r/GCode/CoolingBuffer.hpp | 2 ++ 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/libslic3r/GCode/CoolingBuffer.cpp b/src/libslic3r/GCode/CoolingBuffer.cpp index 9ca85c728..3dcc121c1 100644 --- a/src/libslic3r/GCode/CoolingBuffer.cpp +++ b/src/libslic3r/GCode/CoolingBuffer.cpp @@ -35,6 +35,7 @@ void CoolingBuffer::reset(const Vec3d &position) m_current_pos[1] = float(position.y()); m_current_pos[2] = float(position.z()); m_current_pos[4] = float(m_config.travel_speed.value); + m_fan_speed = -1; } struct CoolingLine @@ -689,10 +690,9 @@ std::string CoolingBuffer::apply_layer_cooldown( // Second generate the adjusted G-code. std::string new_gcode; new_gcode.reserve(gcode.size() * 2); - int fan_speed = -1; bool bridge_fan_control = false; int bridge_fan_speed = 0; - auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &fan_speed, &bridge_fan_control, &bridge_fan_speed ]() { + auto change_extruder_set_fan = [ this, layer_id, layer_time, &new_gcode, &bridge_fan_control, &bridge_fan_speed ]() { #define EXTRUDER_CONFIG(OPT) m_config.OPT.get_at(m_current_extruder) int min_fan_speed = EXTRUDER_CONFIG(min_fan_speed); int fan_speed_new = EXTRUDER_CONFIG(fan_always_on) ? min_fan_speed : 0; @@ -733,9 +733,9 @@ std::string CoolingBuffer::apply_layer_cooldown( bridge_fan_speed = 0; fan_speed_new = 0; } - if (fan_speed_new != fan_speed) { - fan_speed = fan_speed_new; - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, fan_speed); + if (fan_speed_new != m_fan_speed) { + m_fan_speed = fan_speed_new; + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed); } }; @@ -759,7 +759,7 @@ std::string CoolingBuffer::apply_layer_cooldown( new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, bridge_fan_speed); } else if (line->type & CoolingLine::TYPE_BRIDGE_FAN_END) { if (bridge_fan_control) - new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, fan_speed); + new_gcode += GCodeWriter::set_fan(m_config.gcode_flavor, m_config.gcode_comments, m_fan_speed); } else if (line->type & CoolingLine::TYPE_EXTRUDE_END) { // Just remove this comment. } else if (line->type & (CoolingLine::TYPE_ADJUSTABLE | CoolingLine::TYPE_EXTERNAL_PERIMETER | CoolingLine::TYPE_WIPE | CoolingLine::TYPE_HAS_F)) { diff --git a/src/libslic3r/GCode/CoolingBuffer.hpp b/src/libslic3r/GCode/CoolingBuffer.hpp index 5f49ef455..1fe040518 100644 --- a/src/libslic3r/GCode/CoolingBuffer.hpp +++ b/src/libslic3r/GCode/CoolingBuffer.hpp @@ -41,6 +41,8 @@ private: // X,Y,Z,E,F std::vector m_axis; std::vector m_current_pos; + // Current known fan speed or -1 if not known yet. + int m_fan_speed; // Cached from GCodeWriter. // Printing extruder IDs, zero based. std::vector m_extruder_ids; From 5946989c2130a8499c92832cd72b8e775ea0f7fc Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 18 Oct 2021 15:02:13 +0200 Subject: [PATCH 04/18] Stop giving notifications focus on hover. --- src/slic3r/GUI/NotificationManager.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/slic3r/GUI/NotificationManager.cpp b/src/slic3r/GUI/NotificationManager.cpp index 2a27ce74a..40f5c3116 100644 --- a/src/slic3r/GUI/NotificationManager.cpp +++ b/src/slic3r/GUI/NotificationManager.cpp @@ -215,7 +215,8 @@ void NotificationManager::PopNotification::render(GLCanvas3D& canvas, float init } if (mouse_pos.x < win_pos.x && mouse_pos.x > win_pos.x - m_window_width && mouse_pos.y > win_pos.y && mouse_pos.y < win_pos.y + m_window_height) { - ImGui::SetNextWindowFocus(); + // Uncomment if imgui window focus is needed on hover. I cant find any case. + //ImGui::SetNextWindowFocus(); set_hovered(); } From 56c3ea0261497618259220d205657cf7d0a0ac02 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 6 Oct 2021 09:27:50 +0200 Subject: [PATCH 05/18] SendSystemInfo: Use /proc/info instead on lscpu on Linux, center dialog after resizing --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index db6ebad57..e1a6d2d92 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -36,7 +36,9 @@ #include #pragma comment(lib, "iphlpapi.lib") #elif __APPLE__ -#import + #import +#else // Linux/BSD + #include #endif namespace Slic3r { @@ -381,11 +383,15 @@ static std::string generate_system_info_json() cpu_node.put("Model", sysctl["machdep.cpu.brand_string"]); cpu_node.put("Vendor", sysctl["machdep.cpu.vendor"]); #else // linux/BSD - std::map lscpu = parse_lscpu_etc("lscpu", ':'); - cpu_node.put("Arch", lscpu["Architecture"]); - cpu_node.put("Cores", lscpu["CPU(s)"]); - cpu_node.put("Model", lscpu["Model name"]); - cpu_node.put("Vendor", lscpu["Vendor ID"]); + std::map lscpu = parse_lscpu_etc("cat /proc/cpuinfo", ':'); + if (auto ncpu_it = lscpu.find("processor"); ncpu_it != lscpu.end()) { + std::string& ncpu = ncpu_it->second; + if (int num=0; std::from_chars(ncpu.data(), ncpu.data() + ncpu.size(), num).ec != std::errc::invalid_argument) + ncpu = std::to_string(num + 1); + } + cpu_node.put("Cores", lscpu["processor"]); + cpu_node.put("Model", lscpu["model name"]); + cpu_node.put("Vendor", lscpu["vendor_id"]); #endif hw_node.add_child("CPU", cpu_node); @@ -547,6 +553,7 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) const auto size = GetSize(); SetSize(std::max(size.GetWidth(), MIN_WIDTH * em), std::max(size.GetHeight(), MIN_HEIGHT * em)); + CenterOnParent(); m_btn_send->Bind(wxEVT_BUTTON, [this](const wxEvent&) { From f72a5cf1e7059d5d257a895e47cc9a6a39553ca5 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Wed, 6 Oct 2021 15:48:35 +0200 Subject: [PATCH 06/18] SendSystemInfo: Only get the scaling on Win, not on mac or Linux --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index e1a6d2d92..9aaef88b2 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -398,20 +398,17 @@ static std::string generate_system_info_json() pt::ptree monitors_node; for (int i=0; i Date: Wed, 6 Oct 2021 15:49:17 +0200 Subject: [PATCH 07/18] SendSystemInfo: Open the dialog based on appconfig, even in alphas --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 9aaef88b2..6add98e62 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -131,16 +131,14 @@ public: // current version is newer. Only major and minor versions are compared. static bool should_dialog_be_shown() { - return false; - std::string last_sent_version = wxGetApp().app_config->get("version_system_info_sent"); Semver semver_current(SLIC3R_VERSION); Semver semver_last_sent; if (! last_sent_version.empty()) semver_last_sent = Semver(last_sent_version); - if (semver_current.prerelease() && std::string(semver_current.prerelease()) == "alpha") - return false; // Don't show in alphas. + // if (semver_current.prerelease() && std::string(semver_current.prerelease()) == "alpha") + // return false; // Don't show in alphas. // Show the dialog if current > last, but they differ in more than just patch. return ((semver_current.maj() > semver_last_sent.maj()) From ea25461a95bcf0cfab92a909f6f4084d3757129f Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 7 Oct 2021 12:15:31 +0200 Subject: [PATCH 08/18] An attempt to fix the SendSystemInfo dialog on GTK3 --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 6add98e62..7bdf1496d 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -54,8 +54,8 @@ std::string gl_get_string_safe(GLenum param, const std::string& default_value); class SendSystemInfoDialog : public DPIDialog { enum { - MIN_WIDTH = 80, - MIN_HEIGHT = 50 + MIN_WIDTH = 70, + MIN_HEIGHT = 34 }; public: @@ -454,6 +454,8 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) GUI::DPIDialog(parent, wxID_ANY, _L("Send system info"), wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE) { + const int em = GUI::wxGetApp().em_unit(); + // Get current PrusaSliver version info. std::string app_name; { @@ -501,7 +503,7 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) std::string("") + filename + ""); wxString label3 = _L("Show verbatim data that will be sent"); - auto* html_window = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxDefaultSize, wxHW_SCROLLBAR_NEVER); + auto* html_window = new wxHtmlWindow(this, wxID_ANY, wxDefaultPosition, wxSize(70*em, 34*em), wxHW_SCROLLBAR_NEVER); wxString html = GUI::format_wxstr( "" "
" @@ -515,7 +517,7 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) + "" + label3 + "
" + "", bgr_clr_str, text_clr_str); html_window->SetPage(html); - html_window->Bind(wxEVT_HTML_LINK_CLICKED, [this](wxHtmlLinkEvent &evt) { + html_window->Bind(wxEVT_HTML_LINK_CLICKED, [this](wxHtmlLinkEvent&) { ShowJsonDialog dlg(this, m_system_info_json, GetSize().Scale(0.9, 0.7)); dlg.ShowModal(); }); @@ -527,7 +529,6 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) m_btn_send = new wxButton(this, wxID_ANY, _L("Send system info")); auto* hsizer = new wxBoxSizer(wxHORIZONTAL); - const int em = GUI::wxGetApp().em_unit(); hsizer->Add(m_btn_ask_later); hsizer->AddSpacer(em); hsizer->Add(m_btn_dont_send); @@ -548,6 +549,7 @@ SendSystemInfoDialog::SendSystemInfoDialog(wxWindow* parent) const auto size = GetSize(); SetSize(std::max(size.GetWidth(), MIN_WIDTH * em), std::max(size.GetHeight(), MIN_HEIGHT * em)); + CenterOnParent(); m_btn_send->Bind(wxEVT_BUTTON, [this](const wxEvent&) From 8d115def760fb63f3731159b7a26fb1d56bf127b Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Thu, 7 Oct 2021 13:57:00 +0200 Subject: [PATCH 09/18] SendSystemInfo: Trim leading/trailing whitespace from all the values --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 7bdf1496d..908b52252 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -436,15 +436,23 @@ static std::string generate_system_info_json() pt::ptree root; root.add_child("data", data_node); + // Now go through all the values and trim leading/trailing whitespace. + // Some CPU names etc apparently have trailing spaces... + std::function remove_whitespace; + remove_whitespace = [&remove_whitespace](pt::ptree& t) -> void + { + if (t.empty()) // Trim whitespace + boost::algorithm::trim(t.data()); + else + for (auto it = t.begin(); it != t.end(); ++it) + remove_whitespace(it->second); + }; + remove_whitespace(root); + // Serialize the tree into JSON and return it. std::stringstream ss; pt::write_json(ss, root); return ss.str(); - - // FURTHER THINGS TO CONSIDER: - //std::cout << wxPlatformInfo::Get().GetOperatingSystemFamilyName() << std::endl; // Unix - // ? CPU, GPU, UNKNOWN ? - // printers? will they be installed already? } From 13ff92335b6e9423537f71f3e38c36b4bdfab44e Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 8 Oct 2021 12:23:02 +0200 Subject: [PATCH 10/18] Several fixes and improvements in SendSystemInfoDialog: - do not show memory in MB, show it in GiB rounded to one decimal place - when sending fails, the HTTP error code is not presented to the user (it is logged though) - when the user cancels the sending, no extra "sending cancelled" message is shown - in case there is no internet connection, the dialog is not shown at all - a 6 second timeout for a case that connection is lost during sending - the dialog is only shown when the wizard does not show on startup --- src/slic3r/GUI/GUI_App.cpp | 12 ++++--- src/slic3r/GUI/SendSystemInfoDialog.cpp | 43 +++++++++++++++++++------ src/slic3r/Utils/Http.cpp | 15 +++++++++ src/slic3r/Utils/Http.hpp | 2 ++ 4 files changed, 58 insertions(+), 14 deletions(-) diff --git a/src/slic3r/GUI/GUI_App.cpp b/src/slic3r/GUI/GUI_App.cpp index a98998a84..7d6940bd0 100644 --- a/src/slic3r/GUI/GUI_App.cpp +++ b/src/slic3r/GUI/GUI_App.cpp @@ -676,16 +676,18 @@ void GUI_App::post_init() if (this->preset_updater) { this->check_updates(false); CallAfter([this] { - this->config_wizard_startup(); + bool cw_showed = this->config_wizard_startup(); this->preset_updater->slic3r_update_notify(); this->preset_updater->sync(preset_bundle); + if (! cw_showed) { + // The CallAfter is needed as well, without it, GL extensions did not show. + // Also, we only want to show this when the wizard does not, so the new user + // sees something else than "we want something" on the first start. + show_send_system_info_dialog_if_needed(); + } }); } - // 'Send system info' dialog. Again, a CallAfter is needed on mac. - // Without it, GL extensions did not show. - CallAfter([] { show_send_system_info_dialog_if_needed(); }); - #ifdef _WIN32 // Sets window property to mainframe so other instances can indentify it. OtherInstanceMessageHandler::init_windows_properties(mainframe, m_instance_hash_int); diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 908b52252..d90d2223f 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -17,6 +17,7 @@ #include #include #include +#include #include #include @@ -44,6 +45,8 @@ namespace Slic3r { namespace GUI { +static const std::string SEND_SYSTEM_INFO_DOMAIN = "prusa3d.com"; +static const std::string SEND_SYSTEM_INFO_URL = "https://files." + SEND_SYSTEM_INFO_DOMAIN + "/wp-json/v1/ps"; // Declaration of a free function defined in OpenGLManager.cpp: @@ -140,9 +143,24 @@ static bool should_dialog_be_shown() // if (semver_current.prerelease() && std::string(semver_current.prerelease()) == "alpha") // return false; // Don't show in alphas. - // Show the dialog if current > last, but they differ in more than just patch. - return ((semver_current.maj() > semver_last_sent.maj()) + // New version means current > last, but they must differ in more than just patch. + bool new_version = ((semver_current.maj() > semver_last_sent.maj()) || (semver_current.maj() == semver_last_sent.maj() && semver_current.min() > semver_last_sent.min() )); + + if (! new_version) + return false; + + std::cout << "Sending system info was not confirmed/declined in this version yet.\n" + "Pinging prusa3d.com to see if it can be offered now." << std::endl; + bool is_internet = + #ifdef _WIN32 + std::system((std::string("ping /n 1 /w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, 1 sec timeout + #else + std::system((std::string("ping -c 1 -q -w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, quiet output, 1 sec timeout + #endif + std::cout << "Pinging prusa3d.com was " << (is_internet ? "" : "NOT ") << "successful." << std::endl; + + return is_internet; } @@ -364,9 +382,13 @@ static std::string generate_system_info_json() data_node.put("SystemLanguage", sys_language); data_node.put("TranslationLanguage: ", wxGetApp().app_config->get("translation_language")); + pt::ptree hw_node; - hw_node.put("ArchName", wxPlatformInfo::Get().GetArchName()); - hw_node.put("RAM_MB", size_t(Slic3r::total_physical_memory()/1000000)); + { + hw_node.put("ArchName", wxPlatformInfo::Get().GetArchName()); + // Round MiB to hundreds,then present in GiB + hw_node.put("RAM_GiB", std::round(Slic3r::total_physical_memory()/104857600.)/10.); + } // Now get some CPU info: pt::ptree cpu_node; @@ -604,15 +626,16 @@ bool SendSystemInfoDialog::send_info() } result; // No synchronization needed, UI thread reads only after worker is joined. auto send = [&job_done, &result](const std::string& data) { - const std::string url = "https://files.prusa3d.com/wp-json/v1/ps"; - Http http = Http::post(url); + Http http = Http::post(SEND_SYSTEM_INFO_URL); http.header("Content-Type", "application/json") + .timeout_max(6) // seconds .set_post_body(data) .on_complete([&result](std::string body, unsigned status) { result = { Result::Success, _L("System info sent successfully. Thank you.") }; }) .on_error([&result](std::string body, std::string error, unsigned status) { - result = { Result::Error, GUI::format_wxstr(_L("Sending system info failed! Status: %1%"), status) }; + result = { Result::Error, _L("Sending system info failed!") }; + BOOST_LOG_TRIVIAL(error) << "Sending system info failed! STATUS: " << status; }) .on_progress([&job_done, &result](Http::Progress, bool &cancel) { if (job_done) // UI thread wants us to cancel. @@ -634,8 +657,10 @@ bool SendSystemInfoDialog::send_info() job_done = true; // In case the user closed the dialog, let the other thread know sending_thread.join(); // and wait until it terminates. - InfoDialog info_dlg(wxGetApp().mainframe, wxEmptyString, result.str); - info_dlg.ShowModal(); + if (result.value != Result::Cancelled) { // user knows he cancelled, no need to tell him. + InfoDialog info_dlg(wxGetApp().mainframe, wxEmptyString, result.str); + info_dlg.ShowModal(); + } return result.value == Result::Success; } diff --git a/src/slic3r/Utils/Http.cpp b/src/slic3r/Utils/Http.cpp index f1614017f..fc7afbb34 100644 --- a/src/slic3r/Utils/Http.cpp +++ b/src/slic3r/Utils/Http.cpp @@ -104,6 +104,7 @@ struct Http::priv { enum { DEFAULT_TIMEOUT_CONNECT = 10, + DEFAULT_TIMEOUT_MAX = 0, DEFAULT_SIZE_LIMIT = 5 * 1024 * 1024, }; @@ -137,6 +138,7 @@ struct Http::priv static size_t form_file_read_cb(char *buffer, size_t size, size_t nitems, void *userp); void set_timeout_connect(long timeout); + void set_timeout_max(long timeout); void form_add_file(const char *name, const fs::path &path, const char* filename); void set_post_body(const fs::path &path); void set_post_body(const std::string &body); @@ -163,6 +165,7 @@ Http::priv::priv(const std::string &url) } set_timeout_connect(DEFAULT_TIMEOUT_CONNECT); + set_timeout_max(DEFAULT_TIMEOUT_MAX); ::curl_easy_setopt(curl, CURLOPT_URL, url.c_str()); // curl makes a copy internally ::curl_easy_setopt(curl, CURLOPT_USERAGENT, SLIC3R_APP_NAME "/" SLIC3R_VERSION); ::curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, &error_buffer.front()); @@ -253,6 +256,11 @@ void Http::priv::set_timeout_connect(long timeout) ::curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout); } +void Http::priv::set_timeout_max(long timeout) +{ + ::curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); +} + void Http::priv::form_add_file(const char *name, const fs::path &path, const char* filename) { // We can't use CURLFORM_FILECONTENT, because curl doesn't support Unicode filenames on Windows @@ -409,6 +417,13 @@ Http& Http::timeout_connect(long timeout) return *this; } +Http& Http::timeout_max(long timeout) +{ + if (timeout < 1) { timeout = priv::DEFAULT_TIMEOUT_MAX; } + if (p) { p->set_timeout_max(timeout); } + return *this; +} + Http& Http::size_limit(size_t sizeLimit) { if (p) { p->limit = sizeLimit; } diff --git a/src/slic3r/Utils/Http.hpp b/src/slic3r/Utils/Http.hpp index 52e48a394..61d84c51e 100644 --- a/src/slic3r/Utils/Http.hpp +++ b/src/slic3r/Utils/Http.hpp @@ -58,6 +58,8 @@ public: // Sets a maximum connection timeout in seconds Http& timeout_connect(long timeout); + // Sets a maximum total request timeout in seconds + Http& timeout_max(long timeout); // Sets a maximum size of the data that can be received. // A value of zero sets the default limit, which is is 5MB. Http& size_limit(size_t sizeLimit); From 5b20406a33bab21adc7da876880f92f784162355 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 8 Oct 2021 15:15:10 +0200 Subject: [PATCH 11/18] SendSystemInfo: Reporting RAM in GiB --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index d90d2223f..7c444f34a 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -386,8 +386,8 @@ static std::string generate_system_info_json() pt::ptree hw_node; { hw_node.put("ArchName", wxPlatformInfo::Get().GetArchName()); - // Round MiB to hundreds,then present in GiB - hw_node.put("RAM_GiB", std::round(Slic3r::total_physical_memory()/104857600.)/10.); + size_t num = std::round(Slic3r::total_physical_memory()/107374100.); + hw_node.put("RAM_GiB", std::to_string(num / 10) + "." + std::to_string(num % 10)); } // Now get some CPU info: From 692a0dade79b656b8a4b82d19f5a8969b67d445b Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 8 Oct 2021 15:27:45 +0200 Subject: [PATCH 12/18] SendSystemInfo macOS fixes (get system language, fix ping) --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 7c444f34a..72316215a 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -38,6 +38,7 @@ #pragma comment(lib, "iphlpapi.lib") #elif __APPLE__ #import + #include #else // Linux/BSD #include #endif @@ -155,7 +156,9 @@ static bool should_dialog_be_shown() bool is_internet = #ifdef _WIN32 std::system((std::string("ping /n 1 /w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, 1 sec timeout - #else + #elif __APPLE__ + std::system((std::string("ping -c 1 -q -t 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, quiet output, 1 sec timeout + #else // Linux/BSD std::system((std::string("ping -c 1 -q -w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, quiet output, 1 sec timeout #endif std::cout << "Pinging prusa3d.com was " << (is_internet ? "" : "NOT ") << "successful." << std::endl; @@ -336,11 +339,20 @@ static std::string generate_system_info_json() std::string unique_id = get_unique_id(); // Get system language. - std::string sys_language = "Unknown"; - const wxLanguage lang_system = wxLanguage(wxLocale::GetSystemLanguage()); - if (lang_system != wxLANGUAGE_UNKNOWN) - sys_language = wxLocale::GetLanguageInfo(lang_system)->CanonicalName.ToUTF8().data(); - + std::string sys_language = "Unknown"; // important to init, see the __APPLE__ block. + #ifndef __APPLE__ + // Following apparently does not work on macOS. + const wxLanguage lang_system = wxLanguage(wxLocale::GetSystemLanguage()); + if (lang_system != wxLANGUAGE_UNKNOWN) + sys_language = wxLocale::GetLanguageInfo(lang_system)->CanonicalName.ToUTF8().data(); + #else // __APPLE__ + CFLocaleRef cflocale = CFLocaleCopyCurrent(); + CFStringRef value = (CFStringRef)CFLocaleGetValue(cflocale, kCFLocaleLanguageCode); + char temp[10] = ""; + CFStringGetCString(value, temp, 10, kCFStringEncodingUTF8); + sys_language = temp; + CFRelease(cflocale); + #endif // Build a property tree with all the information. namespace pt = boost::property_tree; From 1afa18d7198aad23b1ee0dcf0dd35ba4b6e6fa41 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 12 Oct 2021 15:34:18 +0200 Subject: [PATCH 13/18] SendSystemInfo: Use GET instead of ping to check internet connection --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 22 ++++++++++------------ src/slic3r/Utils/PresetUpdater.cpp | 4 ---- src/slic3r/Utils/PresetUpdater.hpp | 2 ++ 3 files changed, 12 insertions(+), 16 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 72316215a..0b63d52de 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -6,6 +6,7 @@ #include "slic3r/GUI/format.hpp" #include "slic3r/Utils/Http.hpp" +#include "slic3r/Utils/PresetUpdater.hpp" #include "GUI_App.hpp" #include "GUI_Utils.hpp" @@ -151,18 +152,15 @@ static bool should_dialog_be_shown() if (! new_version) return false; - std::cout << "Sending system info was not confirmed/declined in this version yet.\n" - "Pinging prusa3d.com to see if it can be offered now." << std::endl; - bool is_internet = - #ifdef _WIN32 - std::system((std::string("ping /n 1 /w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, 1 sec timeout - #elif __APPLE__ - std::system((std::string("ping -c 1 -q -t 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, quiet output, 1 sec timeout - #else // Linux/BSD - std::system((std::string("ping -c 1 -q -w 1 ") + SEND_SYSTEM_INFO_DOMAIN).data()) == 0; // 1 packet, quiet output, 1 sec timeout - #endif - std::cout << "Pinging prusa3d.com was " << (is_internet ? "" : "NOT ") << "successful." << std::endl; - + // We'll misuse the version check to check internet connection here. + bool is_internet = false; + Http::get(wxGetApp().app_config->version_check_url()) + .size_limit(SLIC3R_VERSION_BODY_MAX) + .timeout_max(2) + .on_complete([&](std::string, unsigned) { + is_internet = true; + }) + .perform_sync(); return is_internet; } diff --git a/src/slic3r/Utils/PresetUpdater.cpp b/src/slic3r/Utils/PresetUpdater.cpp index 13c631c9c..76ecc76d9 100644 --- a/src/slic3r/Utils/PresetUpdater.cpp +++ b/src/slic3r/Utils/PresetUpdater.cpp @@ -46,10 +46,6 @@ using Slic3r::GUI::Config::SnapshotDB; namespace Slic3r { -enum { - SLIC3R_VERSION_BODY_MAX = 256, -}; - static const char *INDEX_FILENAME = "index.idx"; static const char *TMP_EXTENSION = ".download"; diff --git a/src/slic3r/Utils/PresetUpdater.hpp b/src/slic3r/Utils/PresetUpdater.hpp index b7937c574..d0d18a7d8 100644 --- a/src/slic3r/Utils/PresetUpdater.hpp +++ b/src/slic3r/Utils/PresetUpdater.hpp @@ -13,6 +13,8 @@ class AppConfig; class PresetBundle; class Semver; +const int SLIC3R_VERSION_BODY_MAX = 256; + class PresetUpdater { public: From 99bf3d0a25763caf0c64b1def8f5b0e6de24fe58 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Tue, 12 Oct 2021 15:34:41 +0200 Subject: [PATCH 14/18] SendSystemInfo: Show also in alphas, fixed alpha detection --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 0b63d52de..3b9c529a1 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -142,8 +142,12 @@ static bool should_dialog_be_shown() if (! last_sent_version.empty()) semver_last_sent = Semver(last_sent_version); - // if (semver_current.prerelease() && std::string(semver_current.prerelease()) == "alpha") - // return false; // Don't show in alphas. + // set whether to show in alpha builds, or only betas/rcs/finals: + const bool show_in_alphas = true; + + if (! show_in_alphas && semver_current.prerelease() + && std::string(semver_current.prerelease()).find("alpha") != std::string::npos) + return false; // New version means current > last, but they must differ in more than just patch. bool new_version = ((semver_current.maj() > semver_last_sent.maj()) From e30e7ffdef7c24fc336f017b7318eb467fe15b06 Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Fri, 15 Oct 2021 15:16:39 +0200 Subject: [PATCH 15/18] SendSystemInfo: improved error handling --- src/slic3r/GUI/SendSystemInfoDialog.cpp | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/src/slic3r/GUI/SendSystemInfoDialog.cpp b/src/slic3r/GUI/SendSystemInfoDialog.cpp index 3b9c529a1..106617e76 100644 --- a/src/slic3r/GUI/SendSystemInfoDialog.cpp +++ b/src/slic3r/GUI/SendSystemInfoDialog.cpp @@ -185,9 +185,10 @@ static std::map get_cpu_info_from_registry() std::map out; int idx = -1; - constexpr DWORD bufsize_ = 200; - DWORD bufsize = bufsize_; + constexpr DWORD bufsize_ = 500; + DWORD bufsize = bufsize_-1; // Ensure a terminating zero. char buf[bufsize_] = ""; + memset(buf, 0, bufsize_); const std::string reg_dir = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\"; std::string reg_path = reg_dir; @@ -209,7 +210,7 @@ static std::map get_cpu_info_from_registry() } ++idx; reg_path = reg_dir + std::to_string(idx) + "\\"; - bufsize = bufsize_; + bufsize = bufsize_-1; } return out; } @@ -217,7 +218,7 @@ static std::map get_cpu_info_from_registry() static std::map parse_lscpu_etc(const std::string& name, char delimiter) { std::map out; - constexpr size_t max_len = 100; + constexpr size_t max_len = 1000; char cline[max_len] = ""; FILE* fp = popen(name.data(), "r"); if (fp != NULL) { @@ -283,10 +284,12 @@ static std::string get_unique_id() char buf[buf_size] = ""; memset(&buf, 0, sizeof(buf)); io_registry_entry_t ioRegistryRoot = IORegistryEntryFromPath(kIOMasterPortDefault, "IOService:/"); - CFStringRef uuidCf = (CFStringRef)IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0); - IOObjectRelease(ioRegistryRoot); - CFStringGetCString(uuidCf, buf, buf_size, kCFStringEncodingMacRoman); - CFRelease(uuidCf); + if (ioRegistryRoot != MACH_PORT_NULL) { + CFStringRef uuidCf = (CFStringRef)IORegistryEntryCreateCFProperty(ioRegistryRoot, CFSTR(kIOPlatformUUIDKey), kCFAllocatorDefault, 0); + IOObjectRelease(ioRegistryRoot); + CFStringGetCString(uuidCf, buf, buf_size, kCFStringEncodingMacRoman); + CFRelease(uuidCf); + } // Now convert the string to std::vector. for (char* c = buf; *c != 0; ++c) unique.emplace_back((unsigned char)(*c)); From c313e6793a4d837960949fdd26a2511c0066c749 Mon Sep 17 00:00:00 2001 From: Vojtech Bubnik Date: Mon, 18 Oct 2021 15:46:13 +0200 Subject: [PATCH 16/18] Follow-up to 1ca24f0bd03d7f97d576bfac43022733459a9c92 Fixed visualization of G-code in G-code viewer after 07e7e115901c80f282b06ea6b86bc56b28e1a02b The line end positions were not extracted correctly from G-code imported into a stand-alone G-code viewer. --- src/libslic3r/GCodeReader.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libslic3r/GCodeReader.cpp b/src/libslic3r/GCodeReader.cpp index 7b106463a..aa04e69f2 100644 --- a/src/libslic3r/GCodeReader.cpp +++ b/src/libslic3r/GCodeReader.cpp @@ -152,7 +152,7 @@ bool GCodeReader::parse_file_raw_internal(const std::string &filename, ParseLine auto it_end = it; for (; it_end != it_bufend && ! (eol = *it_end == '\r' || *it_end == '\n'); ++ it_end) if (*it_end == '\n') - line_end_callback((it_end - buffer.begin()) + 1); + line_end_callback(file_pos + (it_end - buffer.begin()) + 1); // End of line is indicated also if end of file was reached. eol |= eof && it_end == it_bufend; if (eol) { @@ -173,7 +173,7 @@ bool GCodeReader::parse_file_raw_internal(const std::string &filename, ParseLine if (it != it_bufend && *it == '\r') ++ it; if (it != it_bufend && *it == '\n') { - line_end_callback((it - buffer.begin()) + 1); + line_end_callback(file_pos + (it - buffer.begin()) + 1); ++ it; } } From d3c38fc6039c83a9208d6239d6336ddbe14dab5f Mon Sep 17 00:00:00 2001 From: David Kocik Date: Mon, 18 Oct 2021 15:47:32 +0200 Subject: [PATCH 17/18] Fix of crashing Preferences in Gcode Viewer --- src/slic3r/GUI/Preferences.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/slic3r/GUI/Preferences.cpp b/src/slic3r/GUI/Preferences.cpp index ee80131e0..3748e2251 100644 --- a/src/slic3r/GUI/Preferences.cpp +++ b/src/slic3r/GUI/Preferences.cpp @@ -452,8 +452,10 @@ void PreferencesDialog::build(size_t selected_tab) activate_options_tab(m_optgroup_gui); // set Field for notify_release to its value to activate the object - boost::any val = s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")); - m_optgroup_gui->get_field("notify_release")->set_value(val, false); + if (is_editor) { + boost::any val = s_keys_map_NotifyReleaseMode.at(app_config->get("notify_release")); + m_optgroup_gui->get_field("notify_release")->set_value(val, false); + } if (is_editor) { create_icon_size_slider(); From c12eff19d8d9566e987fa048f938c3a76a37d0bd Mon Sep 17 00:00:00 2001 From: Lukas Matena Date: Mon, 18 Oct 2021 16:24:13 +0200 Subject: [PATCH 18/18] Fixed a possible deadlock: The thread counter should be modified under a mutex, atomic is not enough here --- src/libslic3r/Thread.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libslic3r/Thread.cpp b/src/libslic3r/Thread.cpp index 106da4a78..4e7bd073a 100644 --- a/src/libslic3r/Thread.cpp +++ b/src/libslic3r/Thread.cpp @@ -208,7 +208,7 @@ void name_tbb_thread_pool_threads_set_locale() nthreads = 1; #endif - std::atomic nthreads_running(0); + size_t nthreads_running(0); std::condition_variable cv; std::mutex cv_m; auto master_thread_id = std::this_thread::get_id(); @@ -216,13 +216,13 @@ void name_tbb_thread_pool_threads_set_locale() tbb::blocked_range(0, nthreads, 1), [&nthreads_running, nthreads, &master_thread_id, &cv, &cv_m](const tbb::blocked_range &range) { assert(range.begin() + 1 == range.end()); - if (nthreads_running.fetch_add(1) + 1 == nthreads) { + if (std::unique_lock lk(cv_m); ++nthreads_running == nthreads) { + lk.unlock(); // All threads are spinning. // Wake them up. cv.notify_all(); } else { // Wait for the last thread to wake the others. - std::unique_lock lk(cv_m); cv.wait(lk, [&nthreads_running, nthreads]{return nthreads_running == nthreads;}); } auto thread_id = std::this_thread::get_id();