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