Prusa Slicer 2.6.0
Loading...
Searching...
No Matches
marchsq::__impl::Grid< Rst > Class Template Reference

#include <src/libslic3r/MarchingSquares.hpp>

+ Collaboration diagram for marchsq::__impl::Grid< Rst >:

Classes

struct  CellIt
 
struct  Edge
 

Public Member Functions

 Grid (const Rst &rst, const Coord &cellsz, const Coord &overlap)
 
template<class ExecutionPolicy >
void tag_grid (ExecutionPolicy &&policy, TRasterValue< Rst > isoval)
 
std::vector< Ringscan_rings ()
 
template<class ExecutionPolicy >
void interpolate_rings (ExecutionPolicy &&policy, std::vector< Ring > &rings, TRasterValue< Rst > isov)
 

Private Member Functions

Coord rastercoord (const Coord &crd) const
 
Coord bl (const Coord &crd) const
 
Coord br (const Coord &crd) const
 
Coord tr (const Coord &crd) const
 
Coord tl (const Coord &crd) const
 
bool is_within (const Coord &crd)
 
uint8_t get_tag_for_cell (const Coord &cell, TRasterValue< Rst > v)
 
Coord coord (size_t i) const
 
size_t seq (const Coord &crd) const
 
bool is_visited (size_t idx, Dir d=Dir::none) const
 
void set_visited (size_t idx, Dir d=Dir::none)
 
bool is_ambiguous (size_t idx) const
 
size_t search_start_cell (size_t i=0) const
 
SquareTag get_tag (size_t idx) const
 
Dir next_dir (Dir prev, SquareTag tag) const
 
Edge _edge (const Coord &ringvertex) const
 
Edge edge (const Coord &ringvertex) const
 

Private Attributes

const Rst * m_rst = nullptr
 
Coord m_cellsize
 
Coord m_res_1
 
Coord m_window
 
Coord m_gridsize
 
Coord m_grid_1
 
std::vector< uint8_tm_tags
 

Detailed Description

template<class Rst>
class marchsq::__impl::Grid< Rst >

Class Documentation

◆ marchsq::__impl::Grid::Edge

struct marchsq::__impl::Grid::Edge
template<class Rst>
struct marchsq::__impl::Grid< Rst >::Edge
+ Collaboration diagram for marchsq::__impl::Grid< Rst >::Edge:
Class Members
CellIt from
CellIt to

Constructor & Destructor Documentation

◆ Grid()

template<class Rst >
marchsq::__impl::Grid< Rst >::Grid ( const Rst &  rst,
const Coord cellsz,
const Coord overlap 
)
inlineexplicit
331 : m_rst{&rst}
332 , m_cellsize{cellsz}
333 , m_res_1{m_cellsize.r - 1, m_cellsize.c - 1}
334 , m_window{overlap.r < cellsz.r ? cellsz.r - overlap.r : cellsz.r,
335 overlap.c < cellsz.c ? cellsz.c - overlap.c : cellsz.c}
336 , m_gridsize{2 + (long(rows(rst)) - overlap.r) / m_window.r,
337 2 + (long(cols(rst)) - overlap.c) / m_window.c}
339 {}
Coord m_res_1
Definition MarchingSquares.hpp:145
const Rst * m_rst
Definition MarchingSquares.hpp:144
Coord m_gridsize
Definition MarchingSquares.hpp:145
Coord m_window
Definition MarchingSquares.hpp:145
Coord m_cellsize
Definition MarchingSquares.hpp:145
std::vector< uint8_t > m_tags
Definition MarchingSquares.hpp:146
size_t cols(const T &raster)
Definition MarchingSquares.hpp:60
size_t rows(const T &raster)
Definition MarchingSquares.hpp:55
long c
Definition MarchingSquares.hpp:14
long r
Definition MarchingSquares.hpp:14
wchar_t const wchar_t unsigned long
Definition windows.hpp:29

Member Function Documentation

◆ _edge()

template<class Rst >
Edge marchsq::__impl::Grid< Rst >::_edge ( const Coord ringvertex) const
inlineprivate
261 {
262 size_t idx = ringvertex.r;
263 Coord cell = coord(idx);
264 uint8_t tg = m_tags[ringvertex.r];
265 SquareTag t = SquareTag(tg & 0x0f);
266
267 switch (t) {
268 case SquareTag::a:
269 case SquareTag::ab:
270 case SquareTag::abc:
271 return {{tl(cell), Dir::down, m_rst}, {bl(cell)}};
272 case SquareTag::b:
273 case SquareTag::bc:
274 case SquareTag::bcd:
275 return {{bl(cell), Dir::right, m_rst}, {br(cell)}};
276 case SquareTag::c:
277 return {{br(cell), Dir::up, m_rst}, {tr(cell)}};
278 case SquareTag::ac:
279 switch (Dir(ringvertex.c)) {
280 case Dir::left: return {{tl(cell), Dir::down, m_rst}, {bl(cell)}};
281 case Dir::right: return {{br(cell), Dir::up, m_rst}, {tr(cell)}};
282 default: assert(false);
283 }
284 case SquareTag::d:
285 case SquareTag::ad:
286 case SquareTag::abd:
287 return {{tr(cell), Dir::left, m_rst}, {tl(cell)}};
288 case SquareTag::bd:
289 switch (Dir(ringvertex.c)) {
290 case Dir::down: return {{bl(cell), Dir::right, m_rst}, {br(cell)}};
291 case Dir::up: return {{tr(cell), Dir::left, m_rst}, {tl(cell)}};
292 default: assert(false);
293 }
294 case SquareTag::cd:
295 case SquareTag::acd:
296 return {{br(cell), Dir::up, m_rst}, {tr(cell)}};
297 case SquareTag::full:
298 case SquareTag::none: {
299 Coord crd{tl(cell) + Coord{m_cellsize.r / 2, m_cellsize.c / 2}};
300 return {{crd, Dir::none, m_rst}, {crd}};
301 }
302 }
303
304 return {};
305 }
Coord br(const Coord &crd) const
Definition MarchingSquares.hpp:154
Coord bl(const Coord &crd) const
Definition MarchingSquares.hpp:153
Coord coord(size_t i) const
Definition MarchingSquares.hpp:180
Coord tl(const Coord &crd) const
Definition MarchingSquares.hpp:156
Coord tr(const Coord &crd) const
Definition MarchingSquares.hpp:155
TCoord< PointImpl > Coord
Definition libnest2d.hpp:30
SquareTag
Definition MarchingSquares.hpp:83
Dir
Definition MarchingSquares.hpp:93
unsigned __int8 uint8_t
Definition unistd.h:77

References marchsq::__impl::a, marchsq::__impl::ab, marchsq::__impl::abc, marchsq::__impl::abd, marchsq::__impl::ac, marchsq::__impl::acd, marchsq::__impl::ad, marchsq::__impl::b, marchsq::__impl::bc, marchsq::__impl::bcd, marchsq::__impl::bd, marchsq::__impl::Grid< Rst >::bl(), marchsq::__impl::Grid< Rst >::br(), marchsq::Coord::c, marchsq::__impl::c, marchsq::__impl::cd, marchsq::__impl::Grid< Rst >::coord(), marchsq::__impl::d, marchsq::__impl::down, marchsq::__impl::full, marchsq::__impl::left, marchsq::__impl::Grid< Rst >::m_cellsize, marchsq::__impl::Grid< Rst >::m_rst, marchsq::__impl::Grid< Rst >::m_tags, marchsq::__impl::none, marchsq::Coord::r, marchsq::__impl::right, marchsq::__impl::Grid< Rst >::tl(), marchsq::__impl::Grid< Rst >::tr(), and marchsq::__impl::up.

Referenced by marchsq::__impl::Grid< Rst >::edge().

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

◆ bl()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::bl ( const Coord crd) const
inlineprivate
153{ return tl(crd) + Coord{m_res_1.r, 0}; }

References marchsq::__impl::Grid< Rst >::m_res_1, marchsq::Coord::r, and marchsq::__impl::Grid< Rst >::tl().

Referenced by marchsq::__impl::Grid< Rst >::_edge(), and marchsq::__impl::Grid< Rst >::get_tag_for_cell().

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

◆ br()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::br ( const Coord crd) const
inlineprivate
154{ return tl(crd) + Coord{m_res_1.r, m_res_1.c}; }

References marchsq::Coord::c, marchsq::__impl::Grid< Rst >::m_res_1, marchsq::Coord::r, and marchsq::__impl::Grid< Rst >::tl().

Referenced by marchsq::__impl::Grid< Rst >::_edge(), and marchsq::__impl::Grid< Rst >::get_tag_for_cell().

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

◆ coord()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::coord ( size_t  i) const
inlineprivate
181 {
182 return {long(i) / m_gridsize.c, long(i) % m_gridsize.c};
183 }

References marchsq::Coord::c, long, and marchsq::__impl::Grid< Rst >::m_gridsize.

Referenced by marchsq::__impl::Grid< Rst >::_edge(), and marchsq::__impl::Grid< Rst >::scan_rings().

+ Here is the caller graph for this function:

◆ edge()

template<class Rst >
Edge marchsq::__impl::Grid< Rst >::edge ( const Coord ringvertex) const
inlineprivate
308 {
309 const long R = rows(*m_rst), C = cols(*m_rst);
310 const long R_1 = R - 1, C_1 = C - 1;
311
312 Edge e = _edge(ringvertex);
313 e.to.dir = e.from.dir;
314 ++e.to;
315
316 e.from.crd.r = std::min(e.from.crd.r, R_1);
317 e.from.crd.r = std::max(e.from.crd.r, 0l);
318 e.from.crd.c = std::min(e.from.crd.c, C_1);
319 e.from.crd.c = std::max(e.from.crd.c, 0l);
320
321 e.to.crd.r = std::min(e.to.crd.r, R);
322 e.to.crd.r = std::max(e.to.crd.r, 0l);
323 e.to.crd.c = std::min(e.to.crd.c, C);
324 e.to.crd.c = std::max(e.to.crd.c, 0l);
325
326 return e;
327 }
Edge _edge(const Coord &ringvertex) const
Definition MarchingSquares.hpp:260

References marchsq::__impl::Grid< Rst >::_edge(), marchsq::Coord::c, marchsq::__impl::cols(), marchsq::__impl::Grid< Rst >::CellIt::crd, marchsq::__impl::Grid< Rst >::CellIt::dir, marchsq::__impl::Grid< Rst >::Edge::from, marchsq::__impl::Grid< Rst >::m_rst, marchsq::Coord::r, marchsq::__impl::rows(), and marchsq::__impl::Grid< Rst >::Edge::to.

+ Here is the call graph for this function:

◆ get_tag()

template<class Rst >
SquareTag marchsq::__impl::Grid< Rst >::get_tag ( size_t  idx) const
inlineprivate
216{ return SquareTag(m_tags[idx] & 0x0f); }

References marchsq::__impl::Grid< Rst >::m_tags.

Referenced by marchsq::__impl::Grid< Rst >::is_ambiguous(), marchsq::__impl::Grid< Rst >::is_visited(), and marchsq::__impl::Grid< Rst >::scan_rings().

+ Here is the caller graph for this function:

◆ get_tag_for_cell()

template<class Rst >
uint8_t marchsq::__impl::Grid< Rst >::get_tag_for_cell ( const Coord cell,
TRasterValue< Rst >  v 
)
inlineprivate
167 {
168 Coord sqr[] = {bl(cell), br(cell), tr(cell), tl(cell)};
169
170 uint8_t t = ((is_within(sqr[0]) && isoval(*m_rst, sqr[0]) >= v)) +
171 ((is_within(sqr[1]) && isoval(*m_rst, sqr[1]) >= v) << 1) +
172 ((is_within(sqr[2]) && isoval(*m_rst, sqr[2]) >= v) << 2) +
173 ((is_within(sqr[3]) && isoval(*m_rst, sqr[3]) >= v) << 3);
174
175 assert(t < 16);
176 return t;
177 }
bool is_within(const Coord &crd)
Definition MarchingSquares.hpp:158
constexpr T sqr(T x)
Definition libslic3r.h:258
TRasterValue< T > isoval(const T &rst, const Coord &crd)
Definition MarchingSquares.hpp:65

References marchsq::__impl::Grid< Rst >::bl(), marchsq::__impl::Grid< Rst >::br(), marchsq::__impl::Grid< Rst >::is_within(), marchsq::__impl::isoval(), marchsq::__impl::Grid< Rst >::m_rst, marchsq::__impl::Grid< Rst >::tl(), and marchsq::__impl::Grid< Rst >::tr().

+ Here is the call graph for this function:

◆ interpolate_rings()

template<class Rst >
template<class ExecutionPolicy >
void marchsq::__impl::Grid< Rst >::interpolate_rings ( ExecutionPolicy &&  policy,
std::vector< Ring > &  rings,
TRasterValue< Rst >  isov 
)
inline
394 {
395 for_each(std::forward<ExecutionPolicy>(policy),
396 rings.begin(), rings.end(), [this, isov] (Ring &ring, size_t)
397 {
398 for (Coord &ringvertex : ring) {
399 Edge e = edge(ringvertex);
400
401 CellIt found = std::lower_bound(e.from, e.to, isov);
402 ringvertex = found.crd;
403 }
404 });
405 }
void for_each(ExecutionPolicy &&policy, It from, It to, Fn &&fn)
Definition MarchingSquares.hpp:71
std::vector< Coord > Ring
Definition MarchingSquares.hpp:26

References marchsq::__impl::for_each().

+ Here is the call graph for this function:

◆ is_ambiguous()

template<class Rst >
bool marchsq::__impl::Grid< Rst >::is_ambiguous ( size_t  idx) const
inlineprivate
201 {
202 SquareTag t = get_tag(idx);
203 return t == SquareTag::ac || t == SquareTag::bd;
204 }
SquareTag get_tag(size_t idx) const
Definition MarchingSquares.hpp:216

References marchsq::__impl::ac, marchsq::__impl::bd, and marchsq::__impl::Grid< Rst >::get_tag().

Referenced by marchsq::__impl::Grid< Rst >::search_start_cell().

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

◆ is_visited()

template<class Rst >
bool marchsq::__impl::Grid< Rst >::is_visited ( size_t  idx,
Dir  d = Dir::none 
) const
inlineprivate
188 {
189 SquareTag t = get_tag(idx);
190 uint8_t ref = d == Dir::none ? PREV_CCW[_t(t)] : uint8_t(1 << _t(d));
191 return t == SquareTag::full || t == SquareTag::none ||
192 ((m_tags[idx] & 0xf0) >> 4) == ref;
193 }
static const constexpr uint8_t PREV_CCW[]
Definition MarchingSquares.hpp:114
constexpr std::underlying_type_t< E > _t(E e) noexcept
Definition MarchingSquares.hpp:88

References marchsq::__impl::_t(), marchsq::__impl::d, marchsq::__impl::full, marchsq::__impl::Grid< Rst >::get_tag(), marchsq::__impl::Grid< Rst >::m_tags, marchsq::__impl::none, and marchsq::__impl::PREV_CCW.

Referenced by marchsq::__impl::Grid< Rst >::scan_rings(), and marchsq::__impl::Grid< Rst >::search_start_cell().

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

◆ is_within()

template<class Rst >
bool marchsq::__impl::Grid< Rst >::is_within ( const Coord crd)
inlineprivate
159 {
160 long R = rows(*m_rst), C = cols(*m_rst);
161 return crd.r >= 0 && crd.r < R && crd.c >= 0 && crd.c < C;
162 };

References marchsq::Coord::c, marchsq::__impl::cols(), marchsq::__impl::Grid< Rst >::m_rst, marchsq::Coord::r, and marchsq::__impl::rows().

Referenced by marchsq::__impl::Grid< Rst >::get_tag_for_cell().

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

◆ next_dir()

template<class Rst >
Dir marchsq::__impl::Grid< Rst >::next_dir ( Dir  prev,
SquareTag  tag 
) const
inlineprivate
219 {
220 // Treat ambiguous cases as two separate regions in one square.
221 switch (tag) {
222 case SquareTag::ac:
223 switch (prev) {
224 case Dir::down: return Dir::right;
225 case Dir::up: return Dir::left;
226 default: assert(false); return Dir::none;
227 }
228 case SquareTag::bd:
229 switch (prev) {
230 case Dir::right: return Dir::up;
231 case Dir::left: return Dir::down;
232 default: assert(false); return Dir::none;
233 }
234 default:
235 return NEXT_CCW[uint8_t(tag)];
236 }
237
238 return Dir::none;
239 }
static const constexpr Dir NEXT_CCW[]
Definition MarchingSquares.hpp:95

References marchsq::__impl::ac, marchsq::__impl::bd, marchsq::__impl::down, marchsq::__impl::left, marchsq::__impl::NEXT_CCW, marchsq::__impl::none, marchsq::__impl::right, and marchsq::__impl::up.

Referenced by marchsq::__impl::Grid< Rst >::scan_rings().

+ Here is the caller graph for this function:

◆ rastercoord()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::rastercoord ( const Coord crd) const
inlineprivate
149 {
150 return {(crd.r - 1) * m_window.r, (crd.c - 1) * m_window.c};
151 }

References marchsq::Coord::c, marchsq::__impl::Grid< Rst >::m_window, and marchsq::Coord::r.

Referenced by marchsq::__impl::Grid< Rst >::tl().

+ Here is the caller graph for this function:

◆ scan_rings()

template<class Rst >
std::vector< Ring > marchsq::__impl::Grid< Rst >::scan_rings ( )
inline
357 {
358 std::vector<Ring> rings;
359 size_t startidx = 0;
360 while ((startidx = search_start_cell(startidx)) < m_tags.size()) {
361 Ring ring;
362
363 size_t idx = startidx;
364 Dir prev = Dir::none, next = next_dir(prev, get_tag(idx));
365
366 while (next != Dir::none && !is_visited(idx, prev)) {
367 Coord ringvertex{long(idx), long(next)};
368 ring.emplace_back(ringvertex);
369 set_visited(idx, prev);
370
371 idx = seq(step(coord(idx), next));
372 prev = next;
373 next = next_dir(next, get_tag(idx));
374 }
375
376 // To prevent infinite loops in case of degenerate input
377 if (next == Dir::none) m_tags[startidx] = _t(SquareTag::none);
378
379 if (ring.size() > 1) {
380 ring.pop_back();
381 rings.emplace_back(ring);
382 }
383 }
384
385 return rings;
386 }
size_t search_start_cell(size_t i=0) const
Definition MarchingSquares.hpp:207
Dir next_dir(Dir prev, SquareTag tag) const
Definition MarchingSquares.hpp:218
void set_visited(size_t idx, Dir d=Dir::none)
Definition MarchingSquares.hpp:195
size_t seq(const Coord &crd) const
Definition MarchingSquares.hpp:185
bool is_visited(size_t idx, Dir d=Dir::none) const
Definition MarchingSquares.hpp:187
Coord step(const Coord &crd, Dir d)
Definition MarchingSquares.hpp:137

References marchsq::__impl::_t(), marchsq::__impl::Grid< Rst >::coord(), marchsq::__impl::Grid< Rst >::get_tag(), marchsq::__impl::Grid< Rst >::is_visited(), long, marchsq::__impl::Grid< Rst >::m_tags, marchsq::__impl::Grid< Rst >::next_dir(), marchsq::__impl::none, marchsq::__impl::Grid< Rst >::search_start_cell(), marchsq::__impl::Grid< Rst >::seq(), marchsq::__impl::Grid< Rst >::set_visited(), and marchsq::__impl::step().

+ Here is the call graph for this function:

◆ search_start_cell()

template<class Rst >
size_t marchsq::__impl::Grid< Rst >::search_start_cell ( size_t  i = 0) const
inlineprivate
208 {
209 // Skip ambiguous tags as starting tags due to unknown previous
210 // direction.
211 while ((i < m_tags.size()) && (is_visited(i) || is_ambiguous(i))) ++i;
212
213 return i;
214 }
bool is_ambiguous(size_t idx) const
Definition MarchingSquares.hpp:200

References marchsq::__impl::Grid< Rst >::is_ambiguous(), marchsq::__impl::Grid< Rst >::is_visited(), and marchsq::__impl::Grid< Rst >::m_tags.

Referenced by marchsq::__impl::Grid< Rst >::scan_rings().

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

◆ seq()

template<class Rst >
size_t marchsq::__impl::Grid< Rst >::seq ( const Coord crd) const
inlineprivate
185{ return crd.seq(m_gridsize); }

References marchsq::__impl::Grid< Rst >::m_gridsize, and marchsq::Coord::seq().

Referenced by marchsq::__impl::Grid< Rst >::scan_rings().

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

◆ set_visited()

template<class Rst >
void marchsq::__impl::Grid< Rst >::set_visited ( size_t  idx,
Dir  d = Dir::none 
)
inlineprivate
196 {
197 m_tags[idx] |= (1 << (_t(d)) << 4);
198 }

References marchsq::__impl::_t(), marchsq::__impl::d, and marchsq::__impl::Grid< Rst >::m_tags.

Referenced by marchsq::__impl::Grid< Rst >::scan_rings().

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

◆ tag_grid()

template<class Rst >
template<class ExecutionPolicy >
void marchsq::__impl::Grid< Rst >::tag_grid ( ExecutionPolicy &&  policy,
TRasterValue< Rst >  isoval 
)
inline
344 {
345 // parallel for r
346 for_each (std::forward<ExecutionPolicy>(policy),
347 m_tags.begin(), m_tags.end(),
348 [this, isoval](uint8_t& tag, size_t idx) {
349 tag = get_tag_for_cell(coord(idx), isoval);
350 });
351 }

References marchsq::__impl::for_each(), marchsq::__impl::isoval(), and marchsq::__impl::Grid< Rst >::m_tags.

+ Here is the call graph for this function:

◆ tl()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::tl ( const Coord crd) const
inlineprivate
156{ return rastercoord(crd); }
Coord rastercoord(const Coord &crd) const
Definition MarchingSquares.hpp:148

References marchsq::__impl::Grid< Rst >::rastercoord().

Referenced by marchsq::__impl::Grid< Rst >::_edge(), marchsq::__impl::Grid< Rst >::bl(), marchsq::__impl::Grid< Rst >::br(), marchsq::__impl::Grid< Rst >::get_tag_for_cell(), and marchsq::__impl::Grid< Rst >::tr().

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

◆ tr()

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::tr ( const Coord crd) const
inlineprivate
155{ return tl(crd) + Coord{0, m_res_1.c}; }

References marchsq::Coord::c, marchsq::__impl::Grid< Rst >::m_res_1, and marchsq::__impl::Grid< Rst >::tl().

Referenced by marchsq::__impl::Grid< Rst >::_edge(), and marchsq::__impl::Grid< Rst >::get_tag_for_cell().

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

Member Data Documentation

◆ m_cellsize

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::m_cellsize
private

◆ m_grid_1

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::m_grid_1
private

◆ m_gridsize

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::m_gridsize
private

◆ m_res_1

◆ m_rst

◆ m_tags

◆ m_window

template<class Rst >
Coord marchsq::__impl::Grid< Rst >::m_window
private

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