From 2c8296a9bc7fd4e201e04e4a9b45927817c5f7b7 Mon Sep 17 00:00:00 2001 From: ExPikaPaka Date: Tue, 22 Sep 2026 19:19:54 +0200 Subject: [PATCH] Move polygons instead of copying them on move MultiPoint had no rvalue constructor, so the derived move constructors bound to the const reference and copied; append reserved exactly, so collecting pieces one by one was quadratic. Colour segmentation ~3 s at 0.1 mm / 2000k, was ~40, and ordinary prints gain too. --- src/libslic3r/MultiPoint.hpp | 6 ++++-- src/libslic3r/Polygon.hpp | 4 ++-- src/libslic3r/Polyline.hpp | 4 ++-- src/libslic3r/Support/SupportMaterial.cpp | 2 +- src/libslic3r/Surface.hpp | 4 ++-- src/libslic3r/libslic3r.h | 8 ++++---- 6 files changed, 15 insertions(+), 13 deletions(-) diff --git a/src/libslic3r/MultiPoint.hpp b/src/libslic3r/MultiPoint.hpp index 096230d22c..b4f8af0871 100644 --- a/src/libslic3r/MultiPoint.hpp +++ b/src/libslic3r/MultiPoint.hpp @@ -19,11 +19,13 @@ public: MultiPoint() {} MultiPoint(const MultiPoint &other) : points(other.points) {} - MultiPoint(MultiPoint &&other) : points(std::move(other.points)) {} + MultiPoint(MultiPoint &&other) noexcept : points(std::move(other.points)) {} MultiPoint(std::initializer_list list) : points(list) {} explicit MultiPoint(const Points &_points) : points(_points) {} + // Without it, the derived classes' move constructors passing std::move(points) here copied them. + explicit MultiPoint(Points &&_points) noexcept : points(std::move(_points)) {} MultiPoint& operator=(const MultiPoint &other) { points = other.points; return *this; } - MultiPoint& operator=(MultiPoint &&other) { points = std::move(other.points); return *this; } + MultiPoint& operator=(MultiPoint &&other) noexcept { points = std::move(other.points); return *this; } virtual ~MultiPoint() = default; void scale(double factor); void scale(double factor_x, double factor_y); diff --git a/src/libslic3r/Polygon.hpp b/src/libslic3r/Polygon.hpp index 7d996055e5..d542d2d74a 100644 --- a/src/libslic3r/Polygon.hpp +++ b/src/libslic3r/Polygon.hpp @@ -27,7 +27,7 @@ public: explicit Polygon(const Points &points) : MultiPoint(points) {} Polygon(std::initializer_list points) : MultiPoint(points) {} Polygon(const Polygon &other) : MultiPoint(other.points) {} - Polygon(Polygon &&other) : MultiPoint(std::move(other.points)) {} + Polygon(Polygon &&other) noexcept : MultiPoint(std::move(other.points)) {} static Polygon new_scale(const std::vector &points) { Polygon pgn; pgn.points.reserve(points.size()); @@ -36,7 +36,7 @@ public: return pgn; } Polygon& operator=(const Polygon &other) { points = other.points; return *this; } - Polygon& operator=(Polygon &&other) { points = std::move(other.points); return *this; } + Polygon& operator=(Polygon &&other) noexcept { points = std::move(other.points); return *this; } Point& operator[](Points::size_type idx) { return this->points[idx]; } const Point& operator[](Points::size_type idx) const { return this->points[idx]; } diff --git a/src/libslic3r/Polyline.hpp b/src/libslic3r/Polyline.hpp index f52c3c9bbd..aa9282970e 100644 --- a/src/libslic3r/Polyline.hpp +++ b/src/libslic3r/Polyline.hpp @@ -20,7 +20,7 @@ class Polyline : public MultiPoint { public: Polyline() {}; Polyline(const Polyline& other) : MultiPoint(other.points), fitting_result(other.fitting_result) {} - Polyline(Polyline &&other) : MultiPoint(std::move(other.points)), fitting_result(std::move(other.fitting_result)) {} + Polyline(Polyline &&other) noexcept : MultiPoint(std::move(other.points)), fitting_result(std::move(other.fitting_result)) {} Polyline(std::initializer_list list) : MultiPoint(list) { fitting_result.clear(); } @@ -41,7 +41,7 @@ public: fitting_result = other.fitting_result; return *this; } - Polyline& operator=(Polyline&& other) { + Polyline& operator=(Polyline&& other) noexcept { points = std::move(other.points); fitting_result = std::move(other.fitting_result); return *this; diff --git a/src/libslic3r/Support/SupportMaterial.cpp b/src/libslic3r/Support/SupportMaterial.cpp index a955eb5ca7..ef18ed363f 100644 --- a/src/libslic3r/Support/SupportMaterial.cpp +++ b/src/libslic3r/Support/SupportMaterial.cpp @@ -929,9 +929,9 @@ public: ::fread(&y, sizeof(coord_t), 1, file); poly.points.emplace_back(Point(x * scale, y * scale)); } + printf("Polygon %d, area: %lf\n", i, area(poly.points)); if (which == -1 || which == i) m_support_polygons_deserialized.emplace_back(std::move(poly)); - printf("Polygon %d, area: %lf\n", i, area(poly.points)); } ::fread(&n_polygons, 4, 1, file); m_trimming_polygons_deserialized.reserve(n_polygons); diff --git a/src/libslic3r/Surface.hpp b/src/libslic3r/Surface.hpp index b63c283251..f9737f8cf5 100644 --- a/src/libslic3r/Surface.hpp +++ b/src/libslic3r/Surface.hpp @@ -61,7 +61,7 @@ public: thickness(other.thickness), thickness_layers(other.thickness_layers), bridge_angle(other.bridge_angle), extra_perimeters(other.extra_perimeters) {}; - Surface(Surface &&rhs) + Surface(Surface &&rhs) noexcept : surface_type(rhs.surface_type), expolygon(std::move(rhs.expolygon)), thickness(rhs.thickness), thickness_layers(rhs.thickness_layers), bridge_angle(rhs.bridge_angle), extra_perimeters(rhs.extra_perimeters) @@ -87,7 +87,7 @@ public: return *this; } - Surface& operator=(Surface &&rhs) + Surface& operator=(Surface &&rhs) noexcept { surface_type = rhs.surface_type; expolygon = std::move(rhs.expolygon); diff --git a/src/libslic3r/libslic3r.h b/src/libslic3r/libslic3r.h index c339da566a..06fce9796d 100644 --- a/src/libslic3r/libslic3r.h +++ b/src/libslic3r/libslic3r.h @@ -162,10 +162,10 @@ inline void append(std::vector &dest, std::vector &&src) { if (dest.empty()) dest = std::move(src); - else { - dest.reserve(dest.size() + src.size()); - std::move(std::begin(src), std::end(src), std::back_inserter(dest)); - } + else + // insert() grows the capacity geometrically; reserving exactly the new size reallocated on every call, which + // made appending piece by piece quadratic. + dest.insert(dest.end(), std::make_move_iterator(src.begin()), std::make_move_iterator(src.end())); src.clear(); src.shrink_to_fit(); }