diff --git a/include/utils/polygon.h b/include/utils/polygon.h index 5d9c4c737c..9f32b5fa72 100644 --- a/include/utils/polygon.h +++ b/include/utils/polygon.h @@ -1509,6 +1509,21 @@ class Polygons } Polygons offset(const std::vector& offset_dists) const; + + /*! + * @brief Export the polygon to a WKT string + * + * @param stream The stream to write to + */ + void writeWkt(std::ostream& stream) const; + + /*! + * @brief Import the polygon from a WKT string + * + * @param wkt The WKT string to read from + * @return Polygons The polygons read from the stream + */ + static Polygons fromWkt(const std::string& wkt); }; /*! diff --git a/src/utils/polygon.cpp b/src/utils/polygon.cpp index 5c8884a6ad..d89381078b 100644 --- a/src/utils/polygon.cpp +++ b/src/utils/polygon.cpp @@ -3,18 +3,21 @@ #include "utils/polygon.h" -#include #include -#include -#include +#include +#include +#include +#include +#include +#include #include - -#include "utils/linearAlg2D.h" // pointLiesOnTheRightOfLine +#include +#include #include "utils/ListPolyIt.h" - #include "utils/PolylineStitcher.h" +#include "utils/linearAlg2D.h" // pointLiesOnTheRightOfLine namespace cura { @@ -775,6 +778,55 @@ Polygons Polygons::toPolygons(ClipperLib::PolyTree& poly_tree) return ret; } +Polygons Polygons::fromWkt(const std::string& wkt) +{ + typedef boost::geometry::model::d2::point_xy point_type; + typedef boost::geometry::model::polygon polygon_type; + + polygon_type poly; + boost::geometry::read_wkt(wkt, poly); + + Polygons ret; + + Polygon outer; + for (const auto& point: poly.outer()) + { + outer.add(Point(point.x(), point.y())); + } + ret.add(outer); + + for (const auto& hole: poly.inners()) + { + Polygon inner; + for (const auto& point: hole) + { + inner.add(Point(point.x(), point.y())); + } + ret.add(inner); + } + + return ret; +} + +void Polygons::writeWkt(std::ostream& stream) const +{ + stream << "POLYGON ("; + const auto paths_str = paths + | ranges::views::transform([](const auto& path) { + const auto path_str + = path + | ranges::views::transform([](const auto& point) { return fmt::format("{} {}", point.X, point.Y); }) + | ranges::views::join(ranges::views::c_str(", ")) + | ranges::to(); + return "(" + path_str + ")"; + }) + | ranges::views::join(ranges::views::c_str(" ")) + | ranges::to(); + + stream << paths_str; + stream << ")"; +} + bool ConstPolygonRef::smooth_corner_complex(const Point p1, ListPolyIt& p0_it, ListPolyIt& p2_it, const int64_t shortcut_length) { // walk away from the corner until the shortcut > shortcut_length or it would smooth a piece inward