Blender V5.0
SweepLine.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#pragma once
6
11
12#include <list>
13#include <vector>
14
15#include "MEM_guardedalloc.h"
16
17namespace Freestyle {
18
20template<class Edge> class Intersection {
21 public:
22 template<class EdgeClass> Intersection(EdgeClass *eA, real ta, EdgeClass *eB, real tb)
23 {
24 EdgeA = eA;
25 EdgeB = eB;
26 tA = ta;
27 tB = tb;
28 userdata = 0;
29 }
30
31 Intersection(const Intersection &iBrother)
32 {
33 EdgeA = iBrother.EdgeA;
34 EdgeB = iBrother.EdgeB;
35 tA = iBrother.tA;
36 tB = iBrother.tB;
37 userdata = 0;
38 }
39
42 {
43 if (iEdge == EdgeA) {
44 return tA;
45 }
46 if (iEdge == EdgeB) {
47 return tB;
48 }
49 return 0;
50 }
51
52 public:
53 void *userdata; // FIXME
54
55 Edge *EdgeA; // first segment
56 Edge *EdgeB; // second segment
57 real tA; // parameter defining the intersection point with respect to the segment EdgeA.
58 real tB; // parameter defining the intersection point with respect to the segment EdgeB.
59
60 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Intersection")
61};
62
63#ifdef _MSC_VER
64# pragma warning(push)
65# pragma warning(disable : 4521) // disable warning C4521: multiple copy constructors specified
66#endif
67
68template<class T, class Point> class Segment {
69 public:
71
72 Segment(T &s, const Point &iA, const Point &iB)
73 {
74 _edge = s;
75 if (iA < iB) {
76 A = iA;
77 B = iB;
78 _order = true;
79 }
80 else {
81 A = iB;
82 B = iA;
83 _order = false;
84 }
85 }
86
88 {
89 _edge = iBrother.edge();
90 A = iBrother.A;
91 B = iBrother.B;
92 _Intersections = iBrother._Intersections;
93 _order = iBrother._order;
94 }
95
96 Segment(const Segment<T, Point> &iBrother)
97 {
98 _edge = iBrother._edge;
99 A = iBrother.A;
100 B = iBrother.B;
101 _Intersections = iBrother._Intersections;
102 _order = iBrother._order;
103 }
104
106 {
107 _Intersections.clear();
108 }
109
110 inline Point operator[](const ushort &i) const
111 {
112 return (i % 2 == 0) ? A : B;
113 }
114
115 inline bool operator==(const Segment<T, Point> &iBrother)
116 {
117 if (_edge == iBrother._edge) {
118 return true;
119 }
120 return false;
121 }
122
123 /* Adds an intersection for this segment */
125 {
126 _Intersections.push_back(i);
127 }
128
130 inline bool CommonVertex(const Segment<T, Point> &S, Point &CP)
131 {
132 if ((A == S[0]) || (A == S[1])) {
133 CP = A;
134 return true;
135 }
136 if ((B == S[0]) || (B == S[1])) {
137 CP = B;
138 return true;
139 }
140 return false;
141 }
142
143 inline vector<Intersection<Segment<T, Point>> *> &intersections()
144 {
145 return _Intersections;
146 }
147
148 inline bool order()
149 {
150 return _order;
151 }
152
153 inline T &edge()
154 {
155 return _edge;
156 }
157
158 private:
159 T _edge;
160 Point A;
161 Point B;
162 std::vector<Intersection<Segment<T, Point>> *>
163 _Intersections; // list of intersections parameters
164 bool _order; // true if A and B are in the same order than _edge.A and _edge.B. false otherwise.
165
166 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:Segment")
167};
168
169#ifdef _MSC_VER
170# pragma warning(pop)
171#endif
172
176template<class T1, class T2> struct binary_rule {
178 template<class T3, class T4> binary_rule(const binary_rule<T3, T4> & /*brother*/) {}
179 virtual ~binary_rule() {}
180
181 virtual bool operator()(T1 &, T2 &)
182 {
183 return true;
184 }
185};
186
187template<class T, class Point> class SweepLine {
188 public:
191 {
192 for (typename vector<Intersection<Segment<T, Point>> *>::iterator i = _Intersections.begin(),
193 iend = _Intersections.end();
194 i != iend;
195 i++)
196 {
197 delete (*i);
198 }
199 }
200
201 inline void process(Point &p,
202 vector<Segment<T, Point> *> &segments,
203#if 0
206#else
208#endif
209 real epsilon = M_EPSILON)
210 {
211 // first we remove the segments that need to be removed and then we add the segments to add
212 vector<Segment<T, Point> *> toadd;
213 typename vector<Segment<T, Point> *>::iterator s, send;
214 for (s = segments.begin(), send = segments.end(); s != send; s++) {
215 if (p == (*(*s))[0]) {
216 toadd.push_back((*s));
217 }
218 else {
219 remove((*s));
220 }
221 }
222 for (s = toadd.begin(), send = toadd.end(); s != send; s++) {
223 add((*s), binrule, epsilon);
224 }
225 }
226
227 inline void add(Segment<T, Point> *S,
228#if 0
231#else
233#endif
234 real epsilon)
235 {
236 real t, u;
237 Point CP;
238 Vec2r v0, v1, v2, v3;
239 if (true == S->order()) {
240 v0[0] = ((*S)[0])[0];
241 v0[1] = ((*S)[0])[1];
242 v1[0] = ((*S)[1])[0];
243 v1[1] = ((*S)[1])[1];
244 }
245 else {
246 v1[0] = ((*S)[0])[0];
247 v1[1] = ((*S)[0])[1];
248 v0[0] = ((*S)[1])[0];
249 v0[1] = ((*S)[1])[1];
250 }
251 for (typename std::list<Segment<T, Point> *>::iterator s = _set.begin(), send = _set.end();
252 s != send;
253 s++)
254 {
255 Segment<T, Point> *currentS = (*s);
256 if (true != binrule(*S, *currentS)) {
257 continue;
258 }
259
260 if (true == currentS->order()) {
261 v2[0] = ((*currentS)[0])[0];
262 v2[1] = ((*currentS)[0])[1];
263 v3[0] = ((*currentS)[1])[0];
264 v3[1] = ((*currentS)[1])[1];
265 }
266 else {
267 v3[0] = ((*currentS)[0])[0];
268 v3[1] = ((*currentS)[0])[1];
269 v2[0] = ((*currentS)[1])[0];
270 v2[1] = ((*currentS)[1])[1];
271 }
272 if (S->CommonVertex(*currentS, CP)) {
273 continue; // the two edges have a common vertex->no need to check
274 }
275
276 if (GeomUtils::intersect2dSeg2dSegParametric(v0, v1, v2, v3, t, u, epsilon) ==
278 {
279 // create the intersection
281 S, t, currentS, u);
282 // add it to the intersections list
283 _Intersections.push_back(inter);
284 // add this intersection to the first edge intersections list
285 S->AddIntersection(inter);
286 // add this intersection to the second edge intersections list
287 currentS->AddIntersection(inter);
288 }
289 }
290 // add the added segment to the list of active segments
291 _set.push_back(S);
292 }
293
294 inline void remove(Segment<T, Point> *s)
295 {
296 if (s->intersections().size() > 0) {
297 _IntersectedEdges.push_back(s);
298 }
299 _set.remove(s);
300 }
301
302 vector<Segment<T, Point> *> &intersectedEdges()
303 {
304 return _IntersectedEdges;
305 }
306
307 vector<Intersection<Segment<T, Point>> *> &intersections()
308 {
309 return _Intersections;
310 }
311
312 private:
313 std::list<Segment<T, Point> *>
314 _set; // set of active edges for a given position of the sweep line
315 std::vector<Segment<T, Point> *> _IntersectedEdges; // the list of intersected edges
316 std::vector<Intersection<Segment<T, Point>> *> _Intersections; // the list of all intersections.
317
318 MEM_CXX_CLASS_ALLOC_FUNCS("Freestyle:SweepLine")
319};
320
321} /* namespace Freestyle */
unsigned short ushort
Read Guarded memory(de)allocation.
ATTR_WARN_UNUSED_RESULT const BMVert * v2
#define A
Intersection(EdgeClass *eA, real ta, EdgeClass *eB, real tb)
Definition SweepLine.h:22
real getParameter(Edge *iEdge)
Definition SweepLine.h:41
Intersection(const Intersection &iBrother)
Definition SweepLine.h:31
void AddIntersection(Intersection< Segment< T, Point > > *i)
Definition SweepLine.h:124
vector< Intersection< Segment< T, Point > > * > & intersections()
Definition SweepLine.h:143
Point operator[](const ushort &i) const
Definition SweepLine.h:110
Segment(const Segment< T, Point > &iBrother)
Definition SweepLine.h:96
Segment(T &s, const Point &iA, const Point &iB)
Definition SweepLine.h:72
bool operator==(const Segment< T, Point > &iBrother)
Definition SweepLine.h:115
bool CommonVertex(const Segment< T, Point > &S, Point &CP)
Definition SweepLine.h:130
Segment(Segment< T, Point > &iBrother)
Definition SweepLine.h:87
vector< Intersection< Segment< T, Point > > * > & intersections()
Definition SweepLine.h:307
void add(Segment< T, Point > *S, binary_rule< Segment< T, Point >, Segment< T, Point > > &binrule, real epsilon)
Definition SweepLine.h:227
vector< Segment< T, Point > * > & intersectedEdges()
Definition SweepLine.h:302
void remove(Segment< T, Point > *s)
Definition SweepLine.h:294
void process(Point &p, vector< Segment< T, Point > * > &segments, binary_rule< Segment< T, Point >, Segment< T, Point > > &binrule, real epsilon=M_EPSILON)
Definition SweepLine.h:201
#define T
#define B
#define T2
Definition md5.cpp:21
#define T1
Definition md5.cpp:20
intersection_test intersect2dSeg2dSegParametric(const Vec2r &p1, const Vec2r &p2, const Vec2r &p3, const Vec2r &p4, real &t, real &u, real epsilon)
VecMat::Vec2< real > Vec2r
Definition Geom.h:24
inherits from class Rep
Definition AppCanvas.cpp:20
static const real M_EPSILON
Definition Precision.h:17
double real
Definition Precision.h:14
binary_rule(const binary_rule< T3, T4 > &)
Definition SweepLine.h:178
virtual bool operator()(T1 &, T2 &)
Definition SweepLine.h:181
i
Definition text_draw.cc:230