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
86
87
88
89
90
|
#ifndef __2GEOM_SHAPE_H
#define __2GEOM_SHAPE_H
#include <vector>
#include <set>
#include "region.h"
//TODO: BBOX optimizations
namespace Geom {
enum {
BOOLOP_JUST_A = 1,
BOOLOP_JUST_B = 2,
BOOLOP_BOTH = 4,
BOOLOP_NEITHER = 8
};
enum {
BOOLOP_NULL = 0,
BOOLOP_INTERSECT = BOOLOP_BOTH,
BOOLOP_SUBTRACT_A_B = BOOLOP_JUST_B,
BOOLOP_IDENTITY_A = BOOLOP_JUST_A | BOOLOP_BOTH,
BOOLOP_SUBTRACT_B_A = BOOLOP_JUST_A,
BOOLOP_IDENTITY_B = BOOLOP_JUST_B | BOOLOP_BOTH,
BOOLOP_EXCLUSION = BOOLOP_JUST_A | BOOLOP_JUST_B,
BOOLOP_UNION = BOOLOP_JUST_A | BOOLOP_JUST_B | BOOLOP_BOTH
};
class Shape {
Regions content;
mutable bool fill;
//friend Shape shape_region_boolean(bool rev, Shape const & a, Region const & b);
friend CrossingSet crossings_between(Shape const &a, Shape const &b);
friend Shape shape_boolean(bool rev, Shape const &, Shape const &, CrossingSet const &);
friend Shape boolop(Shape const &a, Shape const &b, unsigned);
friend Shape boolop(Shape const &a, Shape const &b, unsigned, CrossingSet const &);
public:
Shape() : fill(true) {}
explicit Shape(Region const & r) {
content = Regions(1, r);
fill = r.fill;
}
explicit Shape(Regions const & r) : content(r) { update_fill(); }
explicit Shape(bool f) : fill(f) {}
Shape(Regions const & r, bool f) : content(r), fill(f) {}
Regions getContent() const { return content; }
bool isFill() const { return fill; }
unsigned size() const { return content.size(); }
const Region &operator[](unsigned ix) const { return content[ix]; }
Shape inverse() const;
Shape operator*(Matrix const &m) const;
bool contains(Point const &p) const;
bool inside_invariants() const; //semi-slow & easy to violate : checks that the insides are inside, the outsides are outside
bool region_invariants() const; //semi-slow : checks for self crossing
bool cross_invariants() const; //slow : checks that everything is disjoint
bool invariants() const; //vera slow (combo rombo, checks the above)
private:
void update_fill() const {
unsigned ix = outer_index(content);
if(ix < size())
fill = content[ix].fill;
else if(size() > 0)
fill = content.front().fill;
else
fill = true;
}
};
inline CrossingSet crossings_between(Shape const &a, Shape const &b) { return crossings(paths_from_regions(a.content), paths_from_regions(b.content)); }
Shape shape_boolean(bool rev, Shape const &, Shape const &, CrossingSet const &);
Shape shape_boolean(bool rev, Shape const &, Shape const &);
Shape boolop(Shape const &, Shape const &, unsigned flags);
Shape boolop(Shape const &, Shape const &, unsigned flags, CrossingSet &);
Regions regionize_paths(std::vector<Path> const &ps, bool evenodd=true);
}
#endif
|