Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
Slic3r::Arachne::SparsePointGrid< ElemT, Locator > Class Template Reference

Sparse grid which can locate spatially nearby elements efficiently. More...

#include <src/libslic3r/Arachne/utils/SparsePointGrid.hpp>

+ Inheritance diagram for Slic3r::Arachne::SparsePointGrid< ElemT, Locator >:
+ Collaboration diagram for Slic3r::Arachne::SparsePointGrid< ElemT, Locator >:

Public Types

using Elem = ElemT
 
using grid_coord_t = SquareGrid::grid_coord_t
 
using GridMap = std::unordered_multimap< GridPoint, Elem, PointHash >
 
using iterator = typename GridMap::iterator
 
using const_iterator = typename GridMap::const_iterator
 

Public Member Functions

 SparsePointGrid (coord_t cell_size, size_t elem_reserve=0U, float max_load_factor=1.0f)
 Constructs a sparse grid with the specified cell size.
 
void insert (const Elem &elem)
 Inserts elem into the sparse grid.
 
const ElemT * getAnyNearby (const Point &query_pt, coord_t radius)
 
iterator begin ()
 
const_iterator begin () const
 
iterator end ()
 
const_iterator end () const
 
std::vector< ElemgetNearby (const Point &query_pt, coord_t radius) const
 Returns all data within radius of query_pt.
 
bool processNearby (const Point &query_pt, coord_t radius, const std::function< bool(const ElemT &)> &process_func) const
 Process elements from cells that might contain sought after points.
 
bool processNearby (const Point &query_pt, coord_t radius, const std::function< bool(const GridPoint &)> &process_func) const
 Process cells that might contain sought after points.
 
coord_t getCellSize () const
 
bool processLineCells (const std::pair< Point, Point > line, const std::function< bool(GridPoint)> &process_cell_func)
 Process cells along a line indicated by line.
 
bool processLineCells (const std::pair< Point, Point > line, const std::function< bool(GridPoint)> &process_cell_func) const
 Process cells along a line indicated by line.
 
GridPoint toGridPoint (const Vec2i64 &point) const
 Compute the grid coordinates of a point.
 
grid_coord_t toGridCoord (const int64_t &coord) const
 Compute the grid coordinate of a real space coordinate.
 
coord_t toLowerCoord (const grid_coord_t &grid_coord) const
 Compute the lowest coord in a grid cell. The lowest point is the point in the grid cell closest to the origin.
 

Protected Types

using GridPoint = typename SparseGrid< ElemT >::GridPoint
 

Protected Member Functions

bool processFromCell (const GridPoint &grid_pt, const std::function< bool(const Elem &)> &process_func) const
 Process elements from the cell indicated by grid_pt.
 
grid_coord_t nonzeroSign (grid_coord_t z) const
 

Protected Attributes

Locator m_locator
 Accessor for getting locations from elements.
 
GridMap m_grid
 Map from grid locations (GridPoint) to elements (Elem).
 
coord_t cell_size
 The cell (square) size.
 

Detailed Description

template<class ElemT, class Locator>
class Slic3r::Arachne::SparsePointGrid< ElemT, Locator >

Sparse grid which can locate spatially nearby elements efficiently.

Template Parameters
ElemTThe element type to store.
LocatorThe functor to get the location from ElemT. Locator must have: Point operator()(const ElemT &elem) const which returns the location associated with val.

Member Typedef Documentation

◆ const_iterator

template<class ElemT >
using Slic3r::Arachne::SparseGrid< ElemT >::const_iterator = typename GridMap::const_iterator
inherited

◆ Elem

template<class ElemT , class Locator >
using Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::Elem = ElemT

◆ grid_coord_t

template<class ElemT >
using Slic3r::Arachne::SparseGrid< ElemT >::grid_coord_t = SquareGrid::grid_coord_t
inherited

◆ GridMap

template<class ElemT >
using Slic3r::Arachne::SparseGrid< ElemT >::GridMap = std::unordered_multimap<GridPoint, Elem, PointHash>
inherited

◆ GridPoint

template<class ElemT , class Locator >
using Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::GridPoint = typename SparseGrid<ElemT>::GridPoint
protected

◆ iterator

template<class ElemT >
using Slic3r::Arachne::SparseGrid< ElemT >::iterator = typename GridMap::iterator
inherited

Constructor & Destructor Documentation

◆ SparsePointGrid()

template<class ElemT , class Locator >
Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::SparsePointGrid ( coord_t  cell_size,
size_t  elem_reserve = 0U,
float  max_load_factor = 1.0f 
)

Constructs a sparse grid with the specified cell size.

Parameters
[in]cell_sizeThe size to use for a cell (square) in the grid. Typical values would be around 0.5-2x of expected query radius.
[in]elem_reserveNumber of elements to research space for.
[in]max_load_factorMaximum average load factor before rehashing.
60: SparseGrid<ElemT>(cell_size, elem_reserve, max_load_factor) {}
coord_t cell_size
The cell (square) size.
Definition SquareGrid.hpp:94

Member Function Documentation

◆ begin() [1/2]

template<class ElemT >
iterator Slic3r::Arachne::SparseGrid< ElemT >::begin ( )
inlineinherited
45{ return m_grid.begin(); }
GridMap m_grid
Map from grid locations (GridPoint) to elements (Elem).
Definition SparseGrid.hpp:93

References Slic3r::Arachne::SparseGrid< ElemT >::m_grid.

◆ begin() [2/2]

template<class ElemT >
const_iterator Slic3r::Arachne::SparseGrid< ElemT >::begin ( ) const
inlineinherited
47{ return m_grid.begin(); }

References Slic3r::Arachne::SparseGrid< ElemT >::m_grid.

◆ end() [1/2]

template<class ElemT >
iterator Slic3r::Arachne::SparseGrid< ElemT >::end ( )
inlineinherited
46{ return m_grid.end(); }

References Slic3r::Arachne::SparseGrid< ElemT >::m_grid.

◆ end() [2/2]

template<class ElemT >
const_iterator Slic3r::Arachne::SparseGrid< ElemT >::end ( ) const
inlineinherited
48{ return m_grid.end(); }

References Slic3r::Arachne::SparseGrid< ElemT >::m_grid.

◆ getAnyNearby()

template<class ElemT , class Locator >
const ElemT * Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::getAnyNearby ( const Point query_pt,
coord_t  radius 
)

Get just any element that's within a certain radius of a point.

Rather than giving a vector of nearby elements, this function just gives a single element, any element, in no particular order.

Parameters
query_ptThe point to query for an object nearby.
radiusThe radius of what is considered "nearby".
73{
74 const ElemT *ret = nullptr;
75 const std::function<bool(const ElemT &)> &process_func = [&ret, query_pt, radius, this](const ElemT &maybe_nearby) {
76 if (shorter_then(m_locator(maybe_nearby) - query_pt, radius)) {
77 ret = &maybe_nearby;
78 return false;
79 }
80 return true;
81 };
82 SparseGrid<ElemT>::processNearby(query_pt, radius, process_func);
83
84 return ret;
85}
bool processNearby(const Point &query_pt, coord_t radius, const std::function< bool(const ElemT &)> &process_func) const
Process elements from cells that might contain sought after points.
Definition SparseGrid.hpp:114
Locator m_locator
Accessor for getting locations from elements.
Definition SparsePointGrid.hpp:56
bool shorter_then(const Point &p0, const coord_t len)
Definition Point.hpp:301

References Slic3r::Arachne::SparseGrid< ElemT >::processNearby(), and Slic3r::shorter_then().

+ Here is the call graph for this function:

◆ getCellSize()

coord_t SquareGrid::getCellSize ( ) const
inherited

Get the cell size this grid was created for.

145{
146 return cell_size;
147}

References Slic3r::Arachne::SquareGrid::cell_size.

◆ getNearby()

template<class ElemT >
std::vector< typename SparseGrid< ElemT >::Elem > Slic3r::Arachne::SparseGrid< ElemT >::getNearby ( const Point query_pt,
coord_t  radius 
) const
inherited

Returns all data within radius of query_pt.

Finds all elements with location within radius of query_pt. May return additional elements that are beyond radius.

Average running time is a*(1 + 2 * radius / cell_size)**2 + b*cnt where a and b are proportionality constance and cnt is the number of returned items. The search will return items in an area of (2*radius + cell_size)**2 on average. The max range of an item from the query_point is radius + cell_size.

Parameters
[in]query_ptThe point to search around.
[in]radiusThe search radius.
Returns
Vector of elements found
120{
121 std::vector<Elem> ret;
122 const std::function<bool(const Elem &)> process_func = [&ret](const Elem &elem) {
123 ret.push_back(elem);
124 return true;
125 };
126 processNearby(query_pt, radius, process_func);
127 return ret;
128}
ElemT Elem
Definition SparseGrid.hpp:27

◆ insert()

template<class ElemT , class Locator >
void Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::insert ( const Elem elem)

Inserts elem into the sparse grid.

Parameters
[in]elemThe element to be inserted.
64{
65 Point loc = m_locator(elem);
66 GridPoint grid_loc = SparseGrid<ElemT>::toGridPoint(loc.template cast<int64_t>());
67
68 SparseGrid<ElemT>::m_grid.emplace(grid_loc, elem);
69}
typename SparseGrid< ElemT >::GridPoint GridPoint
Definition SparsePointGrid.hpp:53
GridPoint toGridPoint(const Vec2i64 &point) const
Compute the grid coordinates of a point.
Definition SquareGrid.cpp:16
Kernel::Point_2 Point
Definition point_areas.cpp:20

References Slic3r::Arachne::SquareGrid::toGridPoint().

+ Here is the call graph for this function:

◆ nonzeroSign()

SquareGrid::grid_coord_t SquareGrid::nonzeroSign ( grid_coord_t  z) const
protectedinherited

Compute the sign of a number.

The number 0 will result in a positive sign (1).

Parameters
zThe number to find the sign of.
Returns
1 if the number is positive or 0, or -1 if the number is negative.
140{
141 return (z >= 0) - (z < 0);
142}

Referenced by Slic3r::Arachne::SquareGrid::processLineCells().

+ Here is the caller graph for this function:

◆ processFromCell()

template<class ElemT >
bool Slic3r::Arachne::SparseGrid< ElemT >::processFromCell ( const GridPoint grid_pt,
const std::function< bool(const Elem &)> &  process_func 
) const
protectedinherited

Process elements from the cell indicated by grid_pt.

Parameters
[in]grid_ptThe grid coordinates of the cell.
[in]process_funcProcesses each element. process_func(elem) is called for each element in the cell. Processing stops if function returns false.
Returns
Whether we need to continue processing a next cell.
105{
106 auto grid_range = m_grid.equal_range(grid_pt);
107 for (auto iter = grid_range.first; iter != grid_range.second; ++iter)
108 if (!process_func(iter->second))
109 return false;
110 return true;
111}

◆ processLineCells() [1/2]

bool SquareGrid::processLineCells ( const std::pair< Point, Point line,
const std::function< bool(GridPoint)> &  process_cell_func 
)
inherited

Process cells along a line indicated by line.

Parameters
lineThe line along which to process cells.
process_funcProcesses each cell. process_func(elem) is called for each cell. Processing stops if function returns false.
Returns
Whether we need to continue processing after this function.
46{
47 return static_cast<const SquareGrid*>(this)->processLineCells(line, process_cell_func);
48}
Definition SquareGrid.hpp:25
bool processLineCells(const std::pair< Point, Point > line, const std::function< bool(GridPoint)> &process_cell_func)
Process cells along a line indicated by line.
Definition SquareGrid.cpp:45

References Slic3r::Arachne::SquareGrid::processLineCells().

Referenced by Slic3r::Arachne::SparseLineGrid< ElemT, Locator >::insert(), and Slic3r::Arachne::SquareGrid::processLineCells().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ processLineCells() [2/2]

bool SquareGrid::processLineCells ( const std::pair< Point, Point line,
const std::function< bool(GridPoint)> &  process_cell_func 
) const
inherited

Process cells along a line indicated by line.

Parameters
lineThe line along which to process cells
process_funcProcesses each cell. process_func(elem) is called for each cell. Processing stops if function returns false.
Returns
Whether we need to continue processing after this function.
52{
53 Point start = line.first;
54 Point end = line.second;
55 if (end.x() < start.x())
56 { // make sure X increases between start and end
57 std::swap(start, end);
58 }
59
60 const GridPoint start_cell = toGridPoint(start.cast<int64_t>());
61 const GridPoint end_cell = toGridPoint(end.cast<int64_t>());
62 const int64_t y_diff = int64_t(end.y() - start.y());
63 const grid_coord_t y_dir = nonzeroSign(y_diff);
64
65 /* This line drawing algorithm iterates over the range of Y coordinates, and
66 for each Y coordinate computes the range of X coordinates crossed in one
67 unit of Y. These ranges are rounded to be inclusive, so effectively this
68 creates a "fat" line, marking more cells than a strict one-cell-wide path.*/
69 grid_coord_t x_cell_start = start_cell.x();
70 for (grid_coord_t cell_y = start_cell.y(); cell_y * y_dir <= end_cell.y() * y_dir; cell_y += y_dir)
71 { // for all Y from start to end
72 // nearest y coordinate of the cells in the next row
73 const coord_t nearest_next_y = toLowerCoord(cell_y + ((nonzeroSign(cell_y) == y_dir || cell_y == 0) ? y_dir : coord_t(0)));
74 grid_coord_t x_cell_end; // the X coord of the last cell to include from this row
75 if (y_diff == 0)
76 {
77 x_cell_end = end_cell.x();
78 }
79 else
80 {
81 const int64_t area = int64_t(end.x() - start.x()) * int64_t(nearest_next_y - start.y());
82 // corresponding_x: the x coordinate corresponding to nearest_next_y
83 int64_t corresponding_x = int64_t(start.x()) + area / y_diff;
84 x_cell_end = toGridCoord(corresponding_x + ((corresponding_x < 0) && ((area % y_diff) != 0)));
85 if (x_cell_end < start_cell.x())
86 { // process at least one cell!
87 x_cell_end = x_cell_start;
88 }
89 }
90
91 for (grid_coord_t cell_x = x_cell_start; cell_x <= x_cell_end; ++cell_x)
92 {
93 GridPoint grid_loc(cell_x, cell_y);
94 if (! process_cell_func(grid_loc))
95 {
96 return false;
97 }
98 if (grid_loc == end_cell)
99 {
100 return true;
101 }
102 }
103 // TODO: this causes at least a one cell overlap for each row, which
104 // includes extra cells when crossing precisely on the corners
105 // where positive slope where x > 0 and negative slope where x < 0
106 x_cell_start = x_cell_end;
107 }
108 assert(false && "We should have returned already before here!");
109 return false;
110}
grid_coord_t toGridCoord(const int64_t &coord) const
Compute the grid coordinate of a real space coordinate.
Definition SquareGrid.cpp:22
grid_coord_t nonzeroSign(grid_coord_t z) const
Definition SquareGrid.cpp:139
Point GridPoint
Definition SquareGrid.hpp:37
coord_t toLowerCoord(const grid_coord_t &grid_coord) const
Compute the lowest coord in a grid cell. The lowest point is the point in the grid cell closest to th...
Definition SquareGrid.cpp:33
coord_t grid_coord_t
Definition SquareGrid.hpp:38
int32_t coord_t
Definition libslic3r.h:39
double area(const ExPolygon &poly)
Definition ExPolygon.hpp:467
S::iterator end(S &sh, const PathTag &)
Definition geometry_traits.hpp:620
__int64 int64_t
Definition unistd.h:76

References Slic3r::area(), Slic3r::Arachne::SquareGrid::nonzeroSign(), Slic3r::Arachne::SquareGrid::toGridCoord(), Slic3r::Arachne::SquareGrid::toGridPoint(), and Slic3r::Arachne::SquareGrid::toLowerCoord().

+ Here is the call graph for this function:

◆ processNearby() [1/2]

template<class ElemT >
bool Slic3r::Arachne::SparseGrid< ElemT >::processNearby ( const Point query_pt,
coord_t  radius,
const std::function< bool(const ElemT &)> &  process_func 
) const
inherited

Process elements from cells that might contain sought after points.

Processes elements from cell that might have elements within radius of query_pt. Processes all elements that are within radius of query_pt. May process elements that are up to radius + cell_size from query_pt.

Parameters
[in]query_ptThe point to search around.
[in]radiusThe search radius.
[in]process_funcProcesses each element. process_func(elem) is called for each element in the cell. Processing stops if function returns false.
Returns
Whether we need to continue processing after this function
115{
116 return SquareGrid::processNearby(query_pt, radius, [&process_func, this](const GridPoint &grid_pt) { return processFromCell(grid_pt, process_func); });
117}
bool processFromCell(const GridPoint &grid_pt, const std::function< bool(const Elem &)> &process_func) const
Process elements from the cell indicated by grid_pt.
Definition SparseGrid.hpp:104
SquareGrid::GridPoint GridPoint
Definition SparseGrid.hpp:29
bool processNearby(const Point &query_pt, coord_t radius, const std::function< bool(const GridPoint &)> &process_func) const
Process cells that might contain sought after points.
Definition SquareGrid.cpp:113

References Slic3r::Arachne::SquareGrid::processNearby().

Referenced by Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::getAnyNearby().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ processNearby() [2/2]

bool SquareGrid::processNearby ( const Point query_pt,
coord_t  radius,
const std::function< bool(const GridPoint &)> &  process_func 
) const
inherited

Process cells that might contain sought after points.

Processes cells that might be within a square with twice radius as width, centered around query_pt. May process elements that are up to radius + cell_size from query_pt.

Parameters
query_ptThe point to search around.
radiusThe search radius.
process_funcProcesses each cell. process_func(loc) is called for each cell coord within range. Processing stops if function returns false.
Returns
Whether we need to continue processing after this function.
118{
119 const Point min_loc(query_pt.x() - radius, query_pt.y() - radius);
120 const Point max_loc(query_pt.x() + radius, query_pt.y() + radius);
121
122 GridPoint min_grid = toGridPoint(min_loc.cast<int64_t>());
123 GridPoint max_grid = toGridPoint(max_loc.cast<int64_t>());
124
125 for (coord_t grid_y = min_grid.y(); grid_y <= max_grid.y(); ++grid_y)
126 {
127 for (coord_t grid_x = min_grid.x(); grid_x <= max_grid.x(); ++grid_x)
128 {
129 GridPoint grid_pt(grid_x,grid_y);
130 if (!process_func(grid_pt))
131 {
132 return false;
133 }
134 }
135 }
136 return true;
137}

References Slic3r::Arachne::SquareGrid::toGridPoint().

Referenced by Slic3r::Arachne::SparseGrid< ElemT >::processNearby().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toGridCoord()

SquareGrid::grid_coord_t SquareGrid::toGridCoord ( const int64_t coord) const
inherited

Compute the grid coordinate of a real space coordinate.

Parameters
coordThe actual location.
Returns
The grid coordinate that corresponds to coord.
23{
24 // This mapping via truncation results in the cells with
25 // GridPoint.x==0 being twice as large and similarly for
26 // GridPoint.y==0. This doesn't cause any incorrect behavior,
27 // just changes the running time slightly. The change in running
28 // time from this is probably not worth doing a proper floor
29 // operation.
30 return coord / cell_size;
31}

References Slic3r::Arachne::SquareGrid::cell_size.

Referenced by Slic3r::Arachne::SquareGrid::processLineCells(), and Slic3r::Arachne::SquareGrid::toGridPoint().

+ Here is the caller graph for this function:

◆ toGridPoint()

SquareGrid::GridPoint SquareGrid::toGridPoint ( const Vec2i64 point) const
inherited

Compute the grid coordinates of a point.

Parameters
pointThe actual location.
Returns
The grid coordinates that correspond to point.
17{
18 return Point(toGridCoord(point.x()), toGridCoord(point.y()));
19}

References Slic3r::Arachne::SquareGrid::toGridCoord().

Referenced by Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::insert(), Slic3r::Arachne::SquareGrid::processLineCells(), and Slic3r::Arachne::SquareGrid::processNearby().

+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ toLowerCoord()

coord_t SquareGrid::toLowerCoord ( const grid_coord_t grid_coord) const
inherited

Compute the lowest coord in a grid cell. The lowest point is the point in the grid cell closest to the origin.

Parameters
grid_coordThe grid coordinate.
Returns
The print space coordinate that corresponds to grid_coord.
34{
35 // This mapping via truncation results in the cells with
36 // GridPoint.x==0 being twice as large and similarly for
37 // GridPoint.y==0. This doesn't cause any incorrect behavior,
38 // just changes the running time slightly. The change in running
39 // time from this is probably not worth doing a proper floor
40 // operation.
41 return grid_coord * cell_size;
42}

References Slic3r::Arachne::SquareGrid::cell_size.

Referenced by Slic3r::Arachne::SquareGrid::processLineCells().

+ Here is the caller graph for this function:

Member Data Documentation

◆ cell_size

◆ m_grid

◆ m_locator

template<class ElemT , class Locator >
Locator Slic3r::Arachne::SparsePointGrid< ElemT, Locator >::m_locator
protected

Accessor for getting locations from elements.


The documentation for this class was generated from the following file: