Krita Source Code Documentation
Loading...
Searching...
No Matches
KisMagneticGraph.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2019 Kuntal Majumder <hellozee@disroot.org>
3 *
4 * SPDX-License-Identifier: LGPL-2.1-only
5 */
6
7#ifndef KISMAGNETICGRAPH_H
8#define KISMAGNETICGRAPH_H
9
10#include <boost/operators.hpp>
11#include <boost/graph/graph_traits.hpp>
12#include <kis_paint_device.h>
14
15#include <QDebug>
16#include <QRect>
17#include <QColor>
18
20 long x, y;
21
22 enum Direction {
23 MIN = 0,
24 N = MIN, S, E, W, NW, NE, SW, SE, NONE
25 };
26
27 VertexDescriptor(long _x, long _y) :
28 x(_x), y(_y)
29 { }
30
31 VertexDescriptor(QPoint pt) :
32 x(pt.x()), y(pt.y())
33 { }
34
36 x(0), y(0)
37 { }
38
39 bool operator == (VertexDescriptor const &rhs) const
40 {
41 return rhs.x == x && rhs.y == y;
42 }
43
44 bool operator == (QPoint const &rhs) const
45 {
46 return rhs.x() == x && rhs.y() == y;
47 }
48
49 bool operator != (VertexDescriptor const &rhs) const
50 {
51 return rhs.x != x || rhs.y != y;
52 }
53
54 bool operator < (VertexDescriptor const &rhs) const
55 {
56 return x < rhs.x || (x == rhs.x && y < rhs.y);
57 }
58
59 // returns one of the 8 neighboring pixel based on the direction
60 // it gives out multiple warnings, but I am lazy, sorry
62 {
63 int dx = 0, dy = 0;
64
65 switch (direction) {
66 case W:
67 Q_FALLTHROUGH();
68 case SW:
69 Q_FALLTHROUGH();
70 case NW:
71 dx = -1;
72 break;
73 case E:
74 Q_FALLTHROUGH();
75 case SE:
76 Q_FALLTHROUGH();
77 case NE:
78 dx = 1;
79 default:
80 ;
81 }
82
83 switch (direction) {
84 case N:
85 Q_FALLTHROUGH();
86 case NW:
87 Q_FALLTHROUGH();
88 case NE:
89 dy = -1;
90 break;
91 case S:
92 Q_FALLTHROUGH();
93 case SW:
94 Q_FALLTHROUGH();
95 case SE:
96 dy = 1;
97 default:
98 ;
99 }
100
101 VertexDescriptor const neighbor(x + dx, y + dy);
102 return neighbor;
103 } // neighbor
104};
105
106QDebug operator << (QDebug dbg, const VertexDescriptor &v)
107{
108 dbg.nospace() << "(" << v.x << ", " << v.y << ")";
109 return dbg.space();
110}
111
112struct neighbour_iterator;
113
116
118
124
125 KisMagneticGraph(KisPaintDeviceSP dev, QRect graphRect) :
126 m_rect(graphRect), m_dev(dev)
127 {
129 }
130
132 typedef std::pair<vertex_descriptor, vertex_descriptor> edge_descriptor;
133 typedef boost::undirected_tag directed_category;
134 typedef boost::disallow_parallel_edge_tag edge_parallel_category;
135 typedef boost::incidence_graph_tag traversal_category;
137 typedef unsigned degree_size_type;
138
139
141 {
142 m_randAccess->moveTo(pt.x, pt.y);
143 quint8 val = *(m_randAccess->rawData());
144 return val;
145 }
146
148 {
149 // corners
150 if (pt == m_rect.topLeft() || pt == m_rect.topRight() ||
151 pt == m_rect.bottomLeft() || pt == m_rect.bottomRight())
152 {
153 if (m_rect.width() == 1 || m_rect.height() == 1)
154 return 1;
155
156 return 3;
157 }
158
159 // edges
160 if (pt.x == m_rect.topLeft().x() || pt.y == m_rect.topLeft().y() ||
161 pt.x == m_rect.bottomRight().x() || pt.y == m_rect.bottomRight().y())
162 {
163 if (m_rect.width() == 1 || m_rect.height() == 1)
164 return 2;
165
166 return 5;
167 }
168 return 8;
169 }
170
171 QRect m_rect;
172
173private:
176};
177
178struct neighbour_iterator : public boost::iterator_facade<neighbour_iterator
179 , std::pair<VertexDescriptor, VertexDescriptor>
180 , boost::forward_traversal_tag
181 , std::pair<VertexDescriptor, VertexDescriptor> > {
185
188
189 std::pair<VertexDescriptor, VertexDescriptor> operator * () const
190 {
191 std::pair<VertexDescriptor,
192 VertexDescriptor> const result = std::make_pair(m_point, m_point.neighbor(m_direction));
193 return result;
194 }
195
197 {
198 m_direction = static_cast<VertexDescriptor::Direction>(int(m_direction) + 1);
201 return;
202 }
203 if (!m_graph.m_rect.contains(next.x, next.y)) {
204 operator ++ ();
205 }
206 }
207
208 bool operator == (neighbour_iterator const& that) const
209 {
210 return m_point == that.m_point && m_direction == that.m_direction;
211 }
212
213 bool equal(neighbour_iterator const& that) const
214 {
215 return operator == (that);
216 }
217
219 {
220 operator ++ ();
221 }
222
223private:
227};
228
229// Requirements for an Incidence Graph,
230// https://www.boost.org/doc/libs/1_70_0/libs/graph/doc/IncidenceGraph.html
231
232namespace boost {
233template <>
249}
250
252{
253 Q_UNUSED(g);
254 return e.first;
255}
256
258{
259 Q_UNUSED(g);
260 return e.second;
261}
262
263std::pair<KisMagneticGraph::out_edge_iterator, KisMagneticGraph::out_edge_iterator> out_edges(
265{
266 return std::make_pair(
269 );
270}
271
277
278#endif // ifndef KISMAGNETICGRAPH_H
qreal v
std::pair< KisMagneticGraph::out_edge_iterator, KisMagneticGraph::out_edge_iterator > out_edges(typename KisMagneticGraph::vertex_descriptor v, KisMagneticGraph g)
QDebug operator<<(QDebug dbg, const VertexDescriptor &v)
KisMagneticGraph::degree_size_type out_degree(typename KisMagneticGraph::vertex_descriptor v, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
virtual quint8 * rawData()=0
KisRandomAccessorSP createRandomAccessorNG()
virtual void moveTo(qint32 x, qint32 y)=0
neighbour_iterator out_edge_iterator
KisMagneticGraph type
KisPaintDeviceSP m_dev
KisMagneticGraph(KisPaintDeviceSP dev, QRect graphRect)
boost::incidence_graph_tag traversal_category
boost::undirected_tag directed_category
unsigned outDegree(VertexDescriptor pt)
std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor
boost::disallow_parallel_edge_tag edge_parallel_category
quint8 getIntensity(VertexDescriptor pt)
KisRandomAccessorSP m_randAccess
VertexDescriptor vertex_descriptor
KisMagneticGraph(KisPaintDeviceSP dev)
VertexDescriptor(long _x, long _y)
bool operator<(VertexDescriptor const &rhs) const
VertexDescriptor(QPoint pt)
VertexDescriptor neighbor(Direction direction) const
bool operator==(VertexDescriptor const &rhs) const
bool operator!=(VertexDescriptor const &rhs) const
KisMagneticGraph::traversal_category traversal_category
KisMagneticGraph::degree_size_type degree_size_type
KisMagneticGraph::out_edge_iterator out_edge_iterator
KisMagneticGraph::directed_category directed_category
KisMagneticGraph::edge_descriptor edge_descriptor
KisMagneticGraph::edge_parallel_category edge_parallel_category
KisMagneticGraph::vertex_descriptor vertex_descriptor
std::pair< VertexDescriptor, VertexDescriptor > operator*() const
VertexDescriptor::Direction m_direction
VertexDescriptor m_point
neighbour_iterator(VertexDescriptor v, KisMagneticGraph g, VertexDescriptor::Direction d)
bool equal(neighbour_iterator const &that) const
KisMagneticGraph m_graph
bool operator==(neighbour_iterator const &that) const