1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
|
#ifndef __2GEOM_REGION_H
#define __2GEOM_REGION_H
#include "path.h"
#include "path-intersection.h"
namespace Geom {
class Shape;
class Region {
friend Crossings crossings(Region const &a, Region const &b);
friend class Shape;
friend Shape shape_boolean(bool rev, Shape const & a, Shape const & b, CrossingSet const & crs);
Path boundary;
mutable boost::optional<Rect> box;
bool fill;
public:
Region() : fill(true) {}
explicit Region(Path const &p) : boundary(p) { fill = path_direction(p); }
Region(Path const &p, bool dir) : boundary(p), fill(dir) {}
Region(Path const &p, boost::optional<Rect> const &b) : boundary(p), box(b) { fill = path_direction(p); }
Region(Path const &p, boost::optional<Rect> const &b, bool dir) : boundary(p), box(b), fill(dir) {}
unsigned size() const { return boundary.size(); }
bool isFill() const { return fill; }
Region asFill() const { if(fill) return Region(*this); else return inverse(); }
Region asHole() const { if(fill) return inverse(); else return Region(*this); }
operator Path() const { return boundary; }
Rect boundsFast() const {
if(!box) box = boost::optional<Rect>(boundary.boundsFast());
return *box;
}
bool contains(Point const &p) const {
if(box && !box->contains(p)) return false;
return Geom::contains(boundary, p);
}
bool contains(Region const &other) const { return contains(other.boundary.initialPoint()); }
bool includes(Point const &p) const {
return logical_xor(!fill, contains(p));
}
Region inverse() const { return Region(boundary.reverse(), box, !fill); }
Region operator*(Matrix const &m) const;
bool invariants() const;
};
typedef std::vector<Region> Regions;
unsigned outer_index(Regions const &ps);
//assumes they're already sanitized somewhat
inline Regions regions_from_paths(std::vector<Path> const &ps) {
Regions res;
for(unsigned i = 0; i < ps.size(); i++)
res.push_back(Region(ps[i]));
return res;
}
inline std::vector<Path> paths_from_regions(Regions const &rs) {
std::vector<Path> res;
for(unsigned i = 0; i < rs.size(); i++)
res.push_back(rs[i]);
return res;
}
Regions sanitize_path(Path const &p);
Regions region_boolean(bool rev, Region const & a, Region const & b, Crossings const &cr);
Regions region_boolean(bool rev, Region const & a, Region const & b, Crossings const & cr_a, Crossings const & cr_b);
inline Regions region_boolean(bool rev, Region const & a, Region const & b) {
return region_boolean(rev, a, b, crossings(a, b));
}
}
#endif
|