CppNCorr
C++ ncorr Digital Image Correlation engine
Loading...
Searching...
No Matches
ROI2D.h
Go to the documentation of this file.
1/*
2 * File: ROI2D.h
3 * Author: justin
4 *
5 * Created on February 11, 2015, 12:02 AM
6 */
7
8#ifndef ROI2D_H
9#define ROI2D_H
10
11#include <stack>
12
13#include "Array2D.h"
14#include "ncorr/log.h"
15
16
17namespace ncorr {
18
19namespace details {
20 // incrementor is like an iterator, except it does not have the dereference operation
21 class nlinfo_incrementor;
22 class ROI2D_incrementor;
23
24 class ROI2D_contig_subregion_generator; // Forms a contiguous subregion around an (x,y) input
25}
26
27enum class SUBREGION { CIRCLE, SQUARE };
28
29class ROI2D final {
30public:
31 typedef std::ptrdiff_t difference_type;
32 typedef std::pair<difference_type, difference_type> coords;
35
36 struct region_boundary;
37 struct region_nlinfo;
38 struct region;
39
42
43 // Rule of 5 and destructor ----------------------------------------------//
44 ROI2D() : points() { }
45 ROI2D(const ROI2D&) = default;
46 ROI2D(ROI2D&&) noexcept = default;
47 ROI2D& operator=(const ROI2D&) = default;
48 ROI2D& operator=(ROI2D&&) = default;
49 ~ROI2D() noexcept = default;
50
51 // Additional Constructors -----------------------------------------------//
52 explicit ROI2D(Array2D<bool>, difference_type = 0); // by-value
55 ROI2D(std::vector<region_nlinfo>, difference_type, difference_type); // by-value
56 ROI2D(std::vector<region_boundary>, difference_type, difference_type); // by-value
57
58 // Static factory methods ------------------------------------------------//
61 static ROI2D load(std::ifstream&);
62
63 // Operators interface ---------------------------------------------------//
64 friend std::ostream& operator<<(std::ostream&, const ROI2D&);
65 friend void imshow(const ROI2D &roi, difference_type delay = -1) { imshow(*roi.mask_ptr, delay); }
66 friend bool isequal(const ROI2D&, const ROI2D&);
67 friend void save(const ROI2D&, std::ofstream&);
68
69 // Access ----------------------------------------------------------------//
70 // Note that ROI2D is immutable, so all access should be const.
71 difference_type height() const { return mask_ptr->height(); }
72 difference_type width() const { return mask_ptr->width(); }
73 bool empty() const { return points == 0; }
74 bool in_bounds(difference_type p) const { return mask_ptr->in_bounds(p); }
75 bool in_bounds(difference_type p1, difference_type p2) const { return mask_ptr->in_bounds(p1,p2); }
76
77 bool operator()(difference_type p) const { return (*mask_ptr)(p); }
78 bool operator()(difference_type p1, difference_type p2) const { return (*mask_ptr)(p1,p2); }
79 // Perhaps add forwarding of Array2D style region indexing later.
80
81 const Array2D<bool>& get_mask() const { return *mask_ptr; };
82 const region_nlinfo& get_nlinfo(difference_type) const;
83 const region_boundary& get_boundary(difference_type) const;
84 difference_type get_points() const { return points; }
85 difference_type size_regions() const { return regions_ptr->size(); }
86 std::pair<difference_type,difference_type> get_region_idx(difference_type, difference_type) const;
87
88 // Arithmetic operations -------------------------------------------------//
90 ROI2D form_union(const Array2D<bool>&) const;
91
92 // incrementor -----------------------------------------------------------//
93 incrementor begin_inc() const;
94 incrementor end_inc() const;
95
96 // contig_subregion_generator --------------------------------------------//
98
99 // Utility ---------------------------------------------------------------//
100 std::string size_string() const { return mask_ptr->size_string(); }
101 std::string size_2D_string() const { return mask_ptr->size_2D_string(); }
102
103private:
104 // Utility functions -----------------------------------------------------//
105 void set_points();
106 void draw_mask();
107
108 // Checks ----------------------------------------------------------------//
109 void chk_region_idx_in_bounds(difference_type, const std::string&) const;
110
111 std::shared_ptr<Array2D<bool>> mask_ptr; // immutable
112 std::shared_ptr<std::vector<region>> regions_ptr; // immutable
113 difference_type points;
114};
115
116struct ROI2D::region_nlinfo final {
118
119 // nlinfo maintains 4-way contiguity as invariant
120
121 // Rule of 5 and destructor ----------------------------------------------//
123 region_nlinfo(const region_nlinfo&) = default;
127 ~region_nlinfo() noexcept = default;
128
129 friend ROI2D;
130
131 // Additional constructor ------------------------------------------------//
136 difference_type nl_left,
137 difference_type nl_right,
138 difference_type h_nl,
139 difference_type w_nl,
141 bottom(bottom),
142 left(left),
143 right(right),
144 left_nl(nl_left),
145 right_nl(nl_right),
146 nodelist(h_nl,w_nl),
147 noderange(1,w_nl),
148 points(points) { }
149
150 // Static factory methods ------------------------------------------------//
151 static region_nlinfo load(std::ifstream&);
152
153 // Operators interface ---------------------------------------------------//
154 friend std::ostream& operator<<(std::ostream&, const ROI2D::region_nlinfo&);
155 friend bool isequal(const region_nlinfo&, const region_nlinfo&);
156 friend void save(const region_nlinfo&, std::ofstream&);
157
158 // Access methods --------------------------------------------------------//
159 // The following 6 operations are inlined and defined in this header file.
166
167 bool empty() const { return points == 0; }
168
169 // Arithmetic methods ----------------------------------------------------//
172
173 // Incrementor -----------------------------------------------------------//
174 incrementor begin_inc() const;
175 incrementor end_inc() const;
176
177 // Static factory methods ------------------------------------------------//
178 static std::pair<std::vector<ROI2D::region_nlinfo>,bool> form_nlinfos(const Array2D<bool>&, ROI2D::difference_type = 0);
179
184 difference_type left_nl; // left p2 position of beginning of nodelist - can differ from "left"
185 difference_type right_nl; // right p2 position of end of nodelist - can differ from "right"
189
190private:
191 // Arithmetic methods ----------------------------------------------------//
192 // Note that operations on nlinfo must maintain 4-way contiguity invariant
194 region_nlinfo form_union(const Array2D<bool>&, Array2D<bool>&) const;
195 region_nlinfo largest_contig_nlinfo(Array2D<bool>&) const;
196 ROI2D::region_boundary to_boundary(Array2D<bool>&) const;
197
198 // Utility ---------------------------------------------------------------//
199 void chk_nonempty_op(const std::string&) const;
200};
201
203 // Rule of 5 and destructor ----------------------------------------------//
204 region_boundary() = default;
209 ~region_boundary() noexcept = default;
210
211 friend ROI2D;
212
213 // Additional Constructors -----------------------------------------------//
214 region_boundary(const Array2D<double> &add, const std::vector<Array2D<double>> &sub) : add(add), sub(sub) { }
215 region_boundary(const Array2D<double> &add, std::vector<Array2D<double>> &&sub) : add(add), sub(std::move(sub)) { }
216 region_boundary(Array2D<double> &&add, const std::vector<Array2D<double>> &sub) : add(std::move(add)), sub(sub) { }
217 region_boundary(Array2D<double> &&add, std::vector<Array2D<double>> &&sub) : add(std::move(add)), sub(std::move(sub)) { }
218
219 // Static factory methods ------------------------------------------------//
220 static region_boundary load(std::ifstream&);
221
222 // Operators interface ---------------------------------------------------//
223 friend std::ostream& operator<<(std::ostream&, const ROI2D::region_boundary&);
224 friend bool isequal(const region_boundary&, const region_boundary&);
225 friend void save(const region_boundary&, std::ofstream&);
226
228 std::vector<Array2D<double>> sub;
229
230private:
231 // Arithmetic methods ----------------------------------------------------//
232 ROI2D::region_nlinfo to_nlinfo(Array2D<bool>&) const;
233};
234
235struct ROI2D::region final {
236 // Rule of 5 and destructor ----------------------------------------------//
237 region() = default;
238 region(const region&) = default;
239 region(region&&) = default;
240 region& operator=(const region&) = default;
241 region& operator=(region&&) = default;
242 ~region() noexcept = default;
243
244 // Additional Constructors -----------------------------------------------//
249
250 // Static factory methods ------------------------------------------------//
251 static region load(std::ifstream&);
252
253 // Operators interface ---------------------------------------------------//
254 friend std::ostream& operator<<(std::ostream&, const ROI2D::region&);
255 friend bool isequal(const region &reg1, const region &reg2) { return isequal(reg1.nlinfo,reg2.nlinfo) && isequal(reg1.boundary,reg2.boundary); }
256 friend void save(const region&, std::ofstream&);
257
260};
261
262namespace details {
263 // Incrementors ----------------------------------------------------------//
264 class nlinfo_incrementor final {
265 public:
268
269 friend ROI2D::region_nlinfo;
270
271 // Rule of 5 and destructor --------------------------------------//
272 nlinfo_incrementor() noexcept : nlinfo_ptr(nullptr), nl_idx(), np_idx(), p1() { }
277 ~nlinfo_incrementor() noexcept = default;
278
279 // Additional Constructors ---------------------------------------//
280 nlinfo_incrementor(const ROI2D::region_nlinfo &nlinfo, difference_type nl_idx, difference_type np_idx, difference_type p1) :
281 nlinfo_ptr(&nlinfo), nl_idx(nl_idx), np_idx(np_idx), p1(p1) { }
282
283 // Access methods ------------------------------------------------//
284 coords pos_2D() const { return { p1, nlinfo_ptr->left_nl + nl_idx }; }
285
286 // Arithmetic methods --------------------------------------------//
288 // Maybe add decrement operator later
289
290 bool operator==(const nlinfo_incrementor &inc) const {
291 return inc.nlinfo_ptr == nlinfo_ptr && inc.nl_idx == nl_idx && inc.np_idx == np_idx && inc.p1 == p1;
292 }
293 bool operator!=(const nlinfo_incrementor &inc) const { return !(inc == *this); }
294
295 private:
296 const ROI2D::region_nlinfo *nlinfo_ptr;
297 difference_type nl_idx;
298 difference_type np_idx;
299 difference_type p1;
300 };
301
302 class ROI2D_incrementor final {
303 public:
306
307 friend ROI2D;
308
309 // Rule of 5 and destructor --------------------------------------//
310 ROI2D_incrementor() noexcept : region_idx() { }
315 ~ROI2D_incrementor() noexcept = default;
316
317 // Additional Constructors ---------------------------------------//
318 ROI2D_incrementor(const ROI2D&, difference_type, const ROI2D::region_nlinfo::incrementor&);
319
320 // Access methods ------------------------------------------------//
321 coords pos_2D() const { return nlinfo_inc.pos_2D(); }
322
323 // Arithmetic methods --------------------------------------------//
325 // Maybe add decrement operator later
326
327 bool operator==(const ROI2D_incrementor &inc) const {
328 return inc.region_idx == region_idx && inc.nlinfo_inc == nlinfo_inc;
329 }
330 bool operator!=(const ROI2D_incrementor &inc) const { return !(*this == inc); }
331
332 private:
333 ROI2D roi; // ROI2D has pointer semantics
334 difference_type region_idx;
336 };
337
338 // contig_subregion_generator --------------------------------------------//
340 public:
342
343 friend ROI2D;
344
345 // Rule of 5 and destructor --------------------------------------//
352
353 // Additional Constructors ---------------------------------------//
355
356 // Access methods ------------------------------------------------//
357 difference_type get_r() const { return r; }
358 const ROI2D::region_nlinfo& get_subregion_nlinfo() const { return nlinfo_subregion; }
359
360 // Arithmetic methods --------------------------------------------//
362
363 private:
364 ROI2D roi; // ROI2D has pointer semantics
366 mutable Array2D<bool> active_nodepairs;
367 mutable ROI2D::region_nlinfo nlinfo_simple;
368 mutable ROI2D::region_nlinfo nlinfo_subregion;
369 };
370}
371
373 #ifndef NDEBUG
374 chk_nonempty_op("first_pos_idx()");
375 #endif
376
377 return left - left_nl;
378}
379
381 #ifndef NDEBUG
382 chk_nonempty_op("first_pos_p1()");
383 #endif
384
385 return nodelist(0,first_pos_idx());
386}
387
389 #ifndef NDEBUG
390 chk_nonempty_op("first_pos_p2()");
391 #endif
392
393 return left;
394}
395
397 #ifndef NDEBUG
398 chk_nonempty_op("last_pos_idx()");
399 #endif
400
401 return nodelist.width() - (right_nl - right) - 1;
402}
403
405 #ifndef NDEBUG
406 chk_nonempty_op("last_pos_p1()");
407 #endif
408
409 return nodelist(noderange(last_pos_idx()) - 1, last_pos_idx());
410}
411
413 #ifndef NDEBUG
414 chk_nonempty_op("last_pos_p2()");
415 #endif
416
417 return right;
418}
419
420// Interface functions -------------------------------------------------------//
421template <typename T, typename T_container>
422T_container& fill(T_container &A, const ROI2D::region_nlinfo &nlinfo, const T &val) {
424
425 for (difference_type nl_idx = 0; nl_idx < nlinfo.nodelist.width(); ++nl_idx) {
426 difference_type p2 = nl_idx + nlinfo.left_nl;
427 for (difference_type np_idx = 0; np_idx < nlinfo.noderange(nl_idx); np_idx += 2) {
428 difference_type np_top = nlinfo.nodelist(np_idx, nl_idx);
429 difference_type np_bottom = nlinfo.nodelist(np_idx + 1, nl_idx);
430 for (difference_type p1 = np_top; p1 <= np_bottom; ++p1) {
431 A(p1,p2) = val;
432 }
433 }
434 }
435
436 return A;
437}
438
439template <typename T, typename T_container>
440T_container& fill(T_container &A, const Array2D<double>&boundary, const T &val) {
442
443 // Check for empty boundary first - this is not an error, just nothing to fill
444 if (boundary.empty() || boundary.height() == 0) {
445 // If boundary is empty just return
446 NLOG_WARN << "Warning: The boundary is empty or the height is equal 0 - just nothing to fill";
447 return A;
448 }
449
450 if (boundary.width() != 2) {
451 throw std::invalid_argument("Input boundary has size: " + boundary.size_2D_string() + ". Boundary must have a width of 2.");
452 }
453
454 // Flood fill algorithm from : http://alienryderflex.com/polygon_fill/
455 // boundary must have width of 2, where the first column is p1 coordinates
456 // and the second column is p2 coordinates.
457
458 // node_buf is used to hold nodes that are calculated to paint the polygon
459 // along the sweep line. It is initialized to hold at least the max number
460 // of nodes.
461 Array2D<double> node_buf(std::max(boundary.height(),difference_type(2)),1);
462 // Get bounds from max and min of p2 coordinates in boundary. Also note that
463 // boundary is non-empty at this point so min and max exist.
464 difference_type left = std::ceil(std::max(*std::min_element(boundary.get_pointer() + boundary.height() - 1, boundary.get_pointer() + 2 * boundary.height()), 0.0));
465 difference_type right = std::floor(std::min(*std::max_element(boundary.get_pointer() + boundary.height() - 1, boundary.get_pointer() + 2 * boundary.height()), A.width()-1.0));
466 for (difference_type p2_sweep = left; p2_sweep <= right; ++p2_sweep) {
467 difference_type buf_length = 0; // Keeps track of # of nodes
468 // This will cycle over each line segment (point0->point1) of the polygon
469 // and test for intersections with a vertical sweep line on integer pixel
470 // locations.
471 for (difference_type point1_idx = 0, point0_idx = boundary.height() - 1; point1_idx < boundary.height(); point0_idx = point1_idx++) {
472 double point0_p1 = boundary(point0_idx,0), point0_p2 = boundary(point0_idx,1);
473 double point1_p1 = boundary(point1_idx,0), point1_p2 = boundary(point1_idx,1);
474 if ((p2_sweep < point1_p2 && p2_sweep >= point0_p2) ||
475 (p2_sweep < point0_p2 && p2_sweep >= point1_p2)) {
476 node_buf(buf_length++) = point1_p1 + (p2_sweep-point1_p2)/(point0_p2-point1_p2) * (point0_p1-point1_p1);
477 }
478 }
479
480 // Sort nodes
481 std::sort(node_buf.get_pointer(), node_buf.get_pointer() + buf_length);
482
483 // Paint nodes
484 for (difference_type idx = 0; idx < buf_length; idx += 2) {
485 difference_type np_top = std::ceil(node_buf(idx));
486 difference_type np_bottom = std::floor(node_buf(idx+1));
487 if (np_top >= A.height()) {
488 break; // top node is lower than bottom of the mask
489 }
490 if (np_bottom >= 0) { // bottom node is lower than the top of the mask
491 if (np_top < 0) { np_top = 0; }
492 if (np_bottom >= A.height()) { np_bottom = A.height() - 1; }
493
494 // At this point the nodes are within the mask bounds, so paint
495 // them. Note that it's possible for np_top > np_bottom in the
496 // case that the boundary is between two pixels. In this case,
497 // the loop does nothing, so its safe.
498 for (difference_type p1 = np_top; p1 <= np_bottom; p1++) {
499 A(p1,p2_sweep) = val;
500 }
501 }
502 }
503 }
504
505 return A;
506}
507
508template <typename T_container>
509std::pair<typename T_container::value_type, typename T_container::coords> max(T_container &A, const ROI2D::region_nlinfo &nlinfo) {
511
512 if (nlinfo.empty()) {
513 throw std::invalid_argument("Attempted to find the max value in Array using an empty nlinfo.");
514 }
515
516 difference_type p1_max = nlinfo.first_pos_p1();
517 difference_type p2_max = nlinfo.first_pos_p2();
518 difference_type val_max = A(nlinfo.first_pos_idx());
519 for (difference_type nl_idx = 0; nl_idx < nlinfo.nodelist.width(); ++nl_idx) {
520 difference_type p2 = nl_idx + nlinfo.left_nl;
521 for (difference_type np_idx = 0; np_idx < nlinfo.noderange(nl_idx); np_idx += 2) {
522 difference_type np_top = nlinfo.nodelist(np_idx, nl_idx);
523 difference_type np_bottom = nlinfo.nodelist(np_idx + 1, nl_idx);
524 for (difference_type p1 = np_top; p1 <= np_bottom; ++p1) {
525 if (A(p1,p2) > val_max) {
526 p1_max = p1;
527 p2_max = p2;
528 val_max = A(p1,p2);
529 }
530 }
531 }
532 }
533
534 return { val_max, { p1_max,p2_max } };
535}
536
537template <typename T_container>
538std::pair<typename T_container::value_type, typename T_container::coords> min(T_container &A, const ROI2D::region_nlinfo &nlinfo) {
540
541 if (nlinfo.empty()) {
542 throw std::invalid_argument("Attempted to find the min value in Array using an empty nlinfo.");
543 }
544
545 difference_type p1_min = nlinfo.first_pos_p1();
546 difference_type p2_min = nlinfo.first_pos_p2();
547 difference_type val_min = A(nlinfo.first_pos_idx());
548 for (difference_type nl_idx = 0; nl_idx < nlinfo.nodelist.width(); ++nl_idx) {
549 difference_type p2 = nl_idx + nlinfo.left_nl;
550 for (difference_type np_idx = 0; np_idx < nlinfo.noderange(nl_idx); np_idx += 2) {
551 difference_type np_top = nlinfo.nodelist(np_idx, nl_idx);
552 difference_type np_bottom = nlinfo.nodelist(np_idx + 1, nl_idx);
553 for (difference_type p1 = np_top; p1 <= np_bottom; ++p1) {
554 if (A(p1,p2) < val_min) {
555 p1_min = p1;
556 p2_min = p2;
557 val_min = A(p1,p2);
558 }
559 }
560 }
561 }
562
563 return { val_min, { p1_min,p2_min } };
564}
565
566}
567
568#endif /* ROI2D_H */
difference_type width() const
Definition Array2D.h:410
std::string size_2D_string() const
Definition Array2D.h:423
pointer get_pointer() const
Definition Array2D.h:412
difference_type height() const
Definition Array2D.h:409
bool empty() const
Definition Array2D.h:415
friend void save(const ROI2D &, std::ofstream &)
Definition ROI2D.cpp:182
std::pair< difference_type, difference_type > coords
Definition ROI2D.h:32
bool empty() const
Definition ROI2D.h:73
contig_subregion_generator get_contig_subregion_generator(SUBREGION, difference_type) const
Definition ROI2D.cpp:288
friend void imshow(const ROI2D &roi, difference_type delay=-1)
Definition ROI2D.h:65
std::ptrdiff_t difference_type
Definition ROI2D.h:31
friend incrementor
Definition ROI2D.h:40
ROI2D reduce(difference_type) const
Definition ROI2D.cpp:238
bool in_bounds(difference_type p1, difference_type p2) const
Definition ROI2D.h:75
difference_type size_regions() const
Definition ROI2D.h:85
difference_type width() const
Definition ROI2D.h:72
details::ROI2D_incrementor incrementor
Definition ROI2D.h:33
incrementor end_inc() const
Definition ROI2D.cpp:283
bool operator()(difference_type p1, difference_type p2) const
Definition ROI2D.h:78
const Array2D< bool > & get_mask() const
Definition ROI2D.h:81
bool in_bounds(difference_type p) const
Definition ROI2D.h:74
static ROI2D simple_square(difference_type)
Definition ROI2D.cpp:123
incrementor begin_inc() const
Definition ROI2D.cpp:279
const region_nlinfo & get_nlinfo(difference_type) const
Definition ROI2D.cpp:198
ROI2D(ROI2D &&) noexcept=default
std::string size_string() const
Definition ROI2D.h:100
friend bool isequal(const ROI2D &, const ROI2D &)
Definition ROI2D.cpp:164
static ROI2D load(std::ifstream &)
Definition ROI2D.cpp:129
static ROI2D simple_circle(difference_type)
Definition ROI2D.cpp:106
ROI2D form_union(const Array2D< bool > &) const
Definition ROI2D.cpp:258
details::ROI2D_contig_subregion_generator contig_subregion_generator
Definition ROI2D.h:34
friend contig_subregion_generator
Definition ROI2D.h:41
difference_type height() const
Definition ROI2D.h:71
std::pair< difference_type, difference_type > get_region_idx(difference_type, difference_type) const
Definition ROI2D.cpp:210
difference_type get_points() const
Definition ROI2D.h:84
std::string size_2D_string() const
Definition ROI2D.h:101
const region_boundary & get_boundary(difference_type) const
Definition ROI2D.cpp:204
ROI2D(const ROI2D &)=default
bool operator()(difference_type p) const
Definition ROI2D.h:77
ROI2D_contig_subregion_generator & operator=(ROI2D_contig_subregion_generator &&)=default
ROI2D_contig_subregion_generator & operator=(const ROI2D_contig_subregion_generator &)=default
const ROI2D::region_nlinfo & operator()(difference_type, difference_type) const
Definition ROI2D.cpp:1186
ROI2D_contig_subregion_generator(ROI2D_contig_subregion_generator &&)=default
const ROI2D::region_nlinfo & get_subregion_nlinfo() const
Definition ROI2D.h:358
ROI2D_contig_subregion_generator(const ROI2D_contig_subregion_generator &)=default
ROI2D::difference_type difference_type
Definition ROI2D.h:304
ROI2D_incrementor & operator=(const ROI2D_incrementor &)=default
bool operator!=(const ROI2D_incrementor &inc) const
Definition ROI2D.h:330
ROI2D_incrementor & operator++()
Definition ROI2D.cpp:1091
ROI2D_incrementor(const ROI2D_incrementor &)=default
~ROI2D_incrementor() noexcept=default
ROI2D_incrementor & operator=(ROI2D_incrementor &&)=default
bool operator==(const ROI2D_incrementor &inc) const
Definition ROI2D.h:327
ROI2D_incrementor(ROI2D_incrementor &&)=default
bool operator!=(const nlinfo_incrementor &inc) const
Definition ROI2D.h:293
nlinfo_incrementor(nlinfo_incrementor &&)=default
nlinfo_incrementor & operator=(const nlinfo_incrementor &)=default
nlinfo_incrementor & operator++()
Definition ROI2D.cpp:1044
ROI2D::difference_type difference_type
Definition ROI2D.h:266
nlinfo_incrementor & operator=(nlinfo_incrementor &&)=default
~nlinfo_incrementor() noexcept=default
nlinfo_incrementor(const nlinfo_incrementor &)=default
bool operator==(const nlinfo_incrementor &inc) const
Definition ROI2D.h:290
Lightweight, dependency-free logging facility for CppNCorr.
#define NLOG_WARN
Definition log.h:163
T_container & fill(T_container &A, const ROI2D::region_nlinfo &nlinfo, const T &val)
Definition ROI2D.h:422
SUBREGION
Definition ROI2D.h:27
std::pair< typename T_container::value_type, typename T_container::coords > min(T_container &A, const ROI2D::region_nlinfo &nlinfo)
Definition ROI2D.h:538
std::pair< typename T_container::value_type, typename T_container::coords > max(T_container &A, const ROI2D::region_nlinfo &nlinfo)
Definition ROI2D.h:509
static region_boundary load(std::ifstream &)
Definition ROI2D.cpp:927
std::vector< Array2D< double > > sub
Definition ROI2D.h:228
region_boundary & operator=(region_boundary &&)=default
Array2D< double > add
Definition ROI2D.h:227
region_boundary & operator=(const region_boundary &)=default
region_boundary(const region_boundary &)=default
friend std::ostream & operator<<(std::ostream &, const ROI2D::region_boundary &)
Definition ROI2D.cpp:946
region_boundary(const Array2D< double > &add, std::vector< Array2D< double > > &&sub)
Definition ROI2D.h:215
~region_boundary() noexcept=default
region_boundary(region_boundary &&)=default
friend void save(const region_boundary &, std::ofstream &)
Definition ROI2D.cpp:973
friend bool isequal(const region_boundary &, const region_boundary &)
Definition ROI2D.cpp:957
region_boundary(Array2D< double > &&add, const std::vector< Array2D< double > > &sub)
Definition ROI2D.h:216
region_boundary(Array2D< double > &&add, std::vector< Array2D< double > > &&sub)
Definition ROI2D.h:217
~region_nlinfo() noexcept=default
friend std::ostream & operator<<(std::ostream &, const ROI2D::region_nlinfo &)
Definition ROI2D.cpp:338
difference_type top
Definition ROI2D.h:180
difference_type last_pos_p2() const
Definition ROI2D.h:412
difference_type first_pos_p2() const
Definition ROI2D.h:388
incrementor begin_inc() const
Definition ROI2D.cpp:427
Array2D< difference_type > noderange
Definition ROI2D.h:187
details::nlinfo_incrementor incrementor
Definition ROI2D.h:117
region_nlinfo & operator=(region_nlinfo &&)=default
friend bool isequal(const region_nlinfo &, const region_nlinfo &)
Definition ROI2D.cpp:357
difference_type points
Definition ROI2D.h:188
difference_type bottom
Definition ROI2D.h:181
region_nlinfo(const region_nlinfo &)=default
bool in_nlinfo(difference_type, difference_type) const
Definition ROI2D.cpp:387
difference_type right
Definition ROI2D.h:183
difference_type last_pos_p1() const
Definition ROI2D.h:404
static region_nlinfo load(std::ifstream &)
Definition ROI2D.cpp:315
Array2D< difference_type > nodelist
Definition ROI2D.h:186
incrementor end_inc() const
Definition ROI2D.cpp:431
region_nlinfo & shift(difference_type, difference_type)
Definition ROI2D.cpp:405
difference_type left_nl
Definition ROI2D.h:184
region_nlinfo(region_nlinfo &&)=default
region_nlinfo & operator=(const region_nlinfo &)=default
static std::pair< std::vector< ROI2D::region_nlinfo >, bool > form_nlinfos(const Array2D< bool > &, ROI2D::difference_type=0)
Definition ROI2D.cpp:466
difference_type last_pos_idx() const
Definition ROI2D.h:396
friend void save(const region_nlinfo &, std::ofstream &)
Definition ROI2D.cpp:369
difference_type right_nl
Definition ROI2D.h:185
difference_type first_pos_idx() const
Definition ROI2D.h:372
difference_type left
Definition ROI2D.h:182
difference_type first_pos_p1() const
Definition ROI2D.h:380
~region() noexcept=default
region(region_nlinfo &&nlinfo, const region_boundary &boundary)
Definition ROI2D.h:247
friend void save(const region &, std::ofstream &)
Definition ROI2D.cpp:1036
region(const region &)=default
static region load(std::ifstream &)
Definition ROI2D.cpp:1015
region(const region_nlinfo &nlinfo, region_boundary &&boundary)
Definition ROI2D.h:246
region_nlinfo nlinfo
Definition ROI2D.h:258
friend bool isequal(const region &reg1, const region &reg2)
Definition ROI2D.h:255
friend std::ostream & operator<<(std::ostream &, const ROI2D::region &)
Definition ROI2D.cpp:1029
region(region &&)=default
region & operator=(region &&)=default
region & operator=(const region &)=default
region_boundary boundary
Definition ROI2D.h:259
region(region_nlinfo &&nlinfo, region_boundary &&boundary)
Definition ROI2D.h:248