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