diff options
author | bubnikv <bubnikv@gmail.com> | 2018-09-19 12:02:24 +0300 |
---|---|---|
committer | bubnikv <bubnikv@gmail.com> | 2018-09-19 12:02:24 +0300 |
commit | 0558b53493a77bae44831cf87bb0f59359828ef5 (patch) | |
tree | c3e8dbdf7d91a051c12d9ebbf7606d41047fea96 /src/libslic3r/EdgeGrid.hpp | |
parent | 3ddaccb6410478ad02d8c0e02d6d8e6eb1785b9f (diff) |
WIP: Moved sources int src/, separated most of the source code from Perl.
The XS was left only for the unit / integration tests, and it links
libslic3r only. No wxWidgets are allowed to be used from Perl starting
from now.
Diffstat (limited to 'src/libslic3r/EdgeGrid.hpp')
-rw-r--r-- | src/libslic3r/EdgeGrid.hpp | 118 |
1 files changed, 118 insertions, 0 deletions
diff --git a/src/libslic3r/EdgeGrid.hpp b/src/libslic3r/EdgeGrid.hpp new file mode 100644 index 000000000..ab1aa4ed0 --- /dev/null +++ b/src/libslic3r/EdgeGrid.hpp @@ -0,0 +1,118 @@ +#ifndef slic3r_EdgeGrid_hpp_ +#define slic3r_EdgeGrid_hpp_ + +#include <stdint.h> +#include <math.h> + +#include "Point.hpp" +#include "BoundingBox.hpp" +#include "ExPolygon.hpp" +#include "ExPolygonCollection.hpp" + +namespace Slic3r { +namespace EdgeGrid { + +class Grid +{ +public: + Grid(); + ~Grid(); + + void set_bbox(const BoundingBox &bbox) { m_bbox = bbox; } + + void create(const Polygons &polygons, coord_t resolution); + void create(const ExPolygon &expoly, coord_t resolution); + void create(const ExPolygons &expolygons, coord_t resolution); + void create(const ExPolygonCollection &expolygons, coord_t resolution); + +#if 0 + // Test, whether the edges inside the grid intersect with the polygons provided. + bool intersect(const MultiPoint &polyline, bool closed); + bool intersect(const Polygon &polygon) { return intersect(static_cast<const MultiPoint&>(polygon), true); } + bool intersect(const Polygons &polygons) { for (size_t i = 0; i < polygons.size(); ++ i) if (intersect(polygons[i])) return true; return false; } + bool intersect(const ExPolygon &expoly) { if (intersect(expoly.contour)) return true; for (size_t i = 0; i < expoly.holes.size(); ++ i) if (intersect(expoly.holes[i])) return true; return false; } + bool intersect(const ExPolygons &expolygons) { for (size_t i = 0; i < expolygons.size(); ++ i) if (intersect(expolygons[i])) return true; return false; } + bool intersect(const ExPolygonCollection &expolygons) { return intersect(expolygons.expolygons); } + + // Test, whether a point is inside a contour. + bool inside(const Point &pt); +#endif + + // Fill in a rough m_signed_distance_field from the edge grid. + // The rough SDF is used by signed_distance() for distances outside of the search_radius. + void calculate_sdf(); + + // Return an estimate of the signed distance based on m_signed_distance_field grid. + float signed_distance_bilinear(const Point &pt) const; + + // Calculate a signed distance to the contours in search_radius from the point. + bool signed_distance_edges(const Point &pt, coord_t search_radius, coordf_t &result_min_dist, bool *pon_segment = NULL) const; + + // Calculate a signed distance to the contours in search_radius from the point. If no edge is found in search_radius, + // return an interpolated value from m_signed_distance_field, if it exists. + bool signed_distance(const Point &pt, coord_t search_radius, coordf_t &result_min_dist) const; + + const BoundingBox& bbox() const { return m_bbox; } + const coord_t resolution() const { return m_resolution; } + const size_t rows() const { return m_rows; } + const size_t cols() const { return m_cols; } + + // For supports: Contours enclosing the rasterized edges. + Polygons contours_simplified(coord_t offset, bool fill_holes) const; + +protected: + struct Cell { + Cell() : begin(0), end(0) {} + size_t begin; + size_t end; + }; + + void create_from_m_contours(coord_t resolution); +#if 0 + bool line_cell_intersect(const Point &p1, const Point &p2, const Cell &cell); +#endif + bool cell_inside_or_crossing(int r, int c) const + { + if (r < 0 || r >= m_rows || + c < 0 || c >= m_cols) + // The cell is outside the domain. Hoping that the contours were correctly oriented, so + // there is a CCW outmost contour so the out of domain cells are outside. + return false; + const Cell &cell = m_cells[r * m_cols + c]; + return + (cell.begin < cell.end) || + (! m_signed_distance_field.empty() && m_signed_distance_field[r * (m_cols + 1) + c] <= 0.f); + } + + // Bounding box around the contours. + BoundingBox m_bbox; + // Grid dimensions. + coord_t m_resolution; + size_t m_rows; + size_t m_cols; + + // Referencing the source contours. + // This format allows one to work with any Slic3r fixed point contour format + // (Polygon, ExPolygon, ExPolygonCollection etc). + std::vector<const Slic3r::Points*> m_contours; + + // Referencing a contour and a line segment of m_contours. + std::vector<std::pair<size_t, size_t> > m_cell_data; + + // Full grid of cells. + std::vector<Cell> m_cells; + + // Distance field derived from the edge grid, seed filled by the Danielsson chamfer metric. + // May be empty. + std::vector<float> m_signed_distance_field; +}; + +#if 0 +// Debugging utility. Save the signed distance field. +extern void save_png(const Grid &grid, const BoundingBox &bbox, coord_t resolution, const char *path); +#endif /* SLIC3R_GUI */ + +} // namespace EdgeGrid +} // namespace Slic3r + +#endif /* slic3r_EdgeGrid_hpp_ */ |