Krita Source Code Documentation
Loading...
Searching...
No Matches
kis_lazy_fill_graph.h
Go to the documentation of this file.
1/*
2 * SPDX-FileCopyrightText: 2016 Dmitry Kazakov <dimula73@gmail.com>
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7#ifndef __KIS_LAZY_FILL_GRAPH_H
8#define __KIS_LAZY_FILL_GRAPH_H
9
10#include <numeric>
11#include <boost/limits.hpp>
12#include <boost/operators.hpp>
13
14#include <boost/graph/graph_traits.hpp>
15#include <boost/graph/properties.hpp>
16#include <boost/iterator/counting_iterator.hpp>
17#include <boost/iterator/transform_iterator.hpp>
18
19#include <KisRegion.h>
20
21//#define USE_LAZY_FILL_SANITY_CHECKS 1
22
23#ifdef USE_LAZY_FILL_SANITY_CHECKS
24#define LF_SANITY_ASSERT(x) KIS_ASSERT(x)
25#define LF_SANITY_ASSERT_RECOVER(x) KIS_ASSERT_RECOVER(x)
26#else
27#define LF_SANITY_ASSERT(x)
28#define LF_SANITY_ASSERT_RECOVER(x) if (0)
29#endif /* USE_LAZY_FILL_SANITY_CHECKS */
30
31
32using namespace boost;
33
34/*
35BOOST_CONCEPT_ASSERT(( ReadablePropertyMapConcept<ScribbleMap, vertex_descriptor> )); //read flow-values from vertices
36*/
37
39
40//===================
41// Index Property Map
42//===================
43
44template <typename Graph,
45 typename Descriptor,
46 typename Index>
48public:
49 typedef Index value_type;
50 typedef Index reference_type;
52 typedef Descriptor key_type;
53 typedef readable_property_map_tag category;
54
56
57 lazy_fill_graph_index_map(const Graph& graph) :
58 m_graph(&graph) { }
59
61 value_type index = m_graph->index_of(key);
62 LF_SANITY_ASSERT(index >= 0);
63 return index;
64 }
65
66 friend inline Index
69 {
70 return (index_map[key]);
71 }
72
73protected:
74 const Graph* m_graph;
75};
76
77//==========================
78// Reverse Edge Property Map
79//==========================
80
81template <typename Descriptor>
83public:
84 typedef Descriptor value_type;
85 typedef Descriptor reference_type;
87 typedef Descriptor key_type;
88 typedef readable_property_map_tag category;
89
91
92 value_type operator[](const key_type& key) const {
93 return (value_type(key.second, key.first));
94 }
95
96 friend inline Descriptor
99 {
100 return (rev_map[key]);
101 }
102};
103
104//=================
105// Function Objects
106//=================
107
108namespace kis_detail {
109
110 // vertex_at
111 template <typename Graph>
113
114 typedef typename graph_traits<Graph>::vertex_descriptor result_type;
115
117
118 lazy_fill_graph_vertex_at(const Graph* graph) :
119 m_graph(graph) { }
120
122 operator()
123 (typename graph_traits<Graph>::vertices_size_type vertex_index) const {
124 return (vertex(vertex_index, *m_graph));
125 }
126
127 private:
128 const Graph* m_graph;
129 };
130
131 // out_edge_at
132 template <typename Graph>
134
135 private:
136 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
137
138 public:
139 typedef typename graph_traits<Graph>::edge_descriptor result_type;
140
142
144 const Graph* graph) :
145 m_vertex(source_vertex),
146 m_graph(graph) { }
147
149 operator()
150 (typename graph_traits<Graph>::degree_size_type out_edge_index) const {
151 return (out_edge_at(m_vertex, out_edge_index, *m_graph));
152 }
153
154 private:
156 const Graph* m_graph;
157 };
158
159 // in_edge_at
160 template <typename Graph>
162
163 private:
164 typedef typename graph_traits<Graph>::vertex_descriptor vertex_descriptor;
165
166 public:
167 typedef typename graph_traits<Graph>::edge_descriptor result_type;
168
170
172 const Graph* graph) :
173 m_vertex(target_vertex),
174 m_graph(graph) { }
175
177 operator()
178 (typename graph_traits<Graph>::degree_size_type in_edge_index) const {
179 return (in_edge_at(m_vertex, in_edge_index, *m_graph));
180 }
181
182 private:
184 const Graph* m_graph;
185 };
186
187 // edge_at
188 template <typename Graph>
190
191 typedef typename graph_traits<Graph>::edge_descriptor result_type;
192
194
195 lazy_fill_graph_edge_at(const Graph* graph) :
196 m_graph(graph) { }
197
199 operator()
200 (typename graph_traits<Graph>::edges_size_type edge_index) const {
201 return (edge_at(edge_index, *m_graph));
202 }
203
204 private:
205 const Graph* m_graph;
206 };
207
208 // adjacent_vertex_at
209 template <typename Graph>
211
212 public:
213 typedef typename graph_traits<Graph>::vertex_descriptor result_type;
214
216 const Graph* graph) :
217 m_vertex(source_vertex),
218 m_graph(graph) { }
219
221 operator()
222 (typename graph_traits<Graph>::degree_size_type adjacent_index) const {
223 return (target(out_edge_at(m_vertex, adjacent_index, *m_graph), *m_graph));
224 }
225
226 private:
228 const Graph* m_graph;
229 };
230
231} // namespace kis_detail
232
233
235{
236public:
238
239
240 typedef long VertexIndex;
241 typedef long EdgeIndex;
242
243 // sizes
247
248 struct VertexDescriptor : public equality_comparable<VertexDescriptor>
249 {
255
259
261 : x(_x), y(_y), type(_type) {}
262
263 // TODO: Extra constructors look unnecessary, ask Dmitry before removing
265 : x(0), y(0), type(_type) {}
266
268 : x(0), y(0), type(NORMAL) {}
269
270 bool operator ==(const VertexDescriptor &rhs) const {
271 return rhs.x == x && rhs.y == y && rhs.type == type;
272 }
273 };
274
275 // descriptors
277 typedef std::pair<vertex_descriptor, vertex_descriptor> edge_descriptor;
278
279 friend QDebug operator<<(QDebug dbg, const KisLazyFillGraph::edge_descriptor &e);
280 friend QDebug operator<<(QDebug dbg, const KisLazyFillGraph::vertex_descriptor &v);
281
282 // vertex_iterator
283 typedef counting_iterator<vertices_size_type> vertex_index_iterator;
285 typedef transform_iterator<vertex_function, vertex_index_iterator> vertex_iterator;
286
287 // edge_iterator
288 typedef counting_iterator<edges_size_type> edge_index_iterator;
290 typedef transform_iterator<edge_function, edge_index_iterator> edge_iterator;
291
292 // out_edge_iterator
293 typedef counting_iterator<degree_size_type> degree_iterator;
295 typedef transform_iterator<out_edge_function, degree_iterator> out_edge_iterator;
296
297 // adjacency_iterator
299 typedef transform_iterator<adjacent_vertex_function, degree_iterator> adjacency_iterator;
300
301 // categories
302 typedef directed_tag directed_category;
303 typedef disallow_parallel_edge_tag edge_parallel_category;
304 struct traversal_category : virtual public incidence_graph_tag,
305 virtual public adjacency_graph_tag,
306 virtual public vertex_list_graph_tag,
307 virtual public edge_list_graph_tag,
308 virtual public adjacency_matrix_tag { };
309
311 {
312 vertex_descriptor maxed_out_vertex(
313 std::numeric_limits<vertices_size_type>::max(),
314 std::numeric_limits<vertices_size_type>::max(),
316
317 return (maxed_out_vertex);
318 }
319
321
322 KisLazyFillGraph(const QRect &mainRect,
323 const KisRegion &aLabelRegion,
324 const KisRegion &bLabelRegion)
325 : m_x(mainRect.x()),
326 m_y(mainRect.y()),
327 m_width(mainRect.width()),
328 m_height(mainRect.height())
329 {
330 m_mainArea = mainRect;
331 m_aLabelArea = aLabelRegion.boundingRect();
332 m_bLabelArea = bLabelRegion.boundingRect();
333
334 m_aLabelRects = aLabelRegion.rects();
335 m_bLabelRects = bLabelRegion.rects();
336
339
341
342 m_edgeBins << EdgeIndexBin(0, m_mainArea.adjusted(0, 0, -1, 0), HORIZONTAL);
343 m_edgeBins << EdgeIndexBin(m_edgeBins.last(), m_mainArea.adjusted(0, 0, -1, 0), HORIZONTAL_REVERSED);
344
345 m_edgeBins << EdgeIndexBin(m_edgeBins.last(), m_mainArea.adjusted(0, 0, 0, -1), VERTICAL);
346 m_edgeBins << EdgeIndexBin(m_edgeBins.last(), m_mainArea.adjusted(0, 0, 0, -1), VERTICAL_REVERSED);
347
348 Q_FOREACH (const QRect &rc, m_aLabelRects) {
350 }
351
352 // out_edge_at relies on the sequential layout of reversed edges of one type
353 m_aReversedEdgesStart = m_edgeBins.last().last() + 1;
354
355 Q_FOREACH (const QRect &rc, m_aLabelRects) {
357 }
358
359 m_numAEdges = m_edgeBins.last().last() + 1 - m_aReversedEdgesStart;
360
361 Q_FOREACH (const QRect &rc, m_bLabelRects) {
363 }
364
365 // out_edge_at relies on the sequential layout of reversed edges of one type
366 m_bReversedEdgesStart = m_edgeBins.last().last() + 1;
367
368 Q_FOREACH (const QRect &rc, m_bLabelRects) {
370 }
371
372 m_numBEdges = m_edgeBins.last().last() + 1 - m_bReversedEdgesStart;
373
374 m_numEdges = m_edgeBins.last().last() + 1;
375 }
376
378
379 }
380
381 QSize size() const { return QSize(m_width, m_height); }
382 QRect rect() const { return QRect(m_x, m_y, m_width, m_height); }
383
384
387
390
393
398
409
412 : start(0), stride(0), size(0) {}
413
415 const QRect &_rect,
416 EdgeIndexBinId _binId)
417 : start(_start),
418 stride(_rect.width()),
419 size(_rect.width() * _rect.height()),
420 xOffset(_rect.x()),
421 yOffset(_rect.y()),
422 binId(_binId),
423 isReversed(int(_binId) & 0x1),
424 rect(_rect) {}
425
426 EdgeIndexBin(const EdgeIndexBin &putAfter,
427 const QRect &_rect,
428 EdgeIndexBinId _binId)
429 : start(putAfter.last() + 1),
430 stride(_rect.width()),
431 size(_rect.width() * _rect.height()),
432 xOffset(_rect.x()),
433 yOffset(_rect.y()),
434 binId(_binId),
435 isReversed(int(_binId) & 0x1),
436 rect(_rect) {}
437
439 return start + size - 1;
440 }
441
442 bool contains(edges_size_type index) const {
443 index -= start;
444 return index >= 0 && index < size;
445 }
446
447 bool contains(const edge_descriptor &edge) const {
448 return indexOf(edge) >= 0;
449 }
450
452 vertex_descriptor src_vertex = source(edge, *this);
453 vertex_descriptor dst_vertex = target(edge, *this);
454
455 const bool srcColoredA = src_vertex.type == vertex_descriptor::LABEL_A;
456 const bool dstColoredA = dst_vertex.type == vertex_descriptor::LABEL_A;
457 const bool srcColoredB = src_vertex.type == vertex_descriptor::LABEL_B;
458 const bool dstColoredB = dst_vertex.type == vertex_descriptor::LABEL_B;
459
460 if (srcColoredA || dstColoredA) {
461 const bool edgeReversed = srcColoredA;
462
463 if (isReversed != edgeReversed ||
464 (binId != LABEL_A && binId != LABEL_A_REVERSED) ||
465 (srcColoredA && (dst_vertex.type != vertex_descriptor::NORMAL)) ||
466 (dstColoredA && (src_vertex.type != vertex_descriptor::NORMAL))) {
467
468 return -1;
469 }
470 } else if (srcColoredB || dstColoredB) {
471 const bool edgeReversed = srcColoredB;
472
473 if (isReversed != edgeReversed ||
474 (binId != LABEL_B && binId != LABEL_B_REVERSED) ||
475 (srcColoredB && (dst_vertex.type != vertex_descriptor::NORMAL)) ||
476 (dstColoredB && (src_vertex.type != vertex_descriptor::NORMAL))) {
477
478 return -1;
479 }
480 } else {
481 const vertices_size_type xDiff = dst_vertex.x - src_vertex.x;
482 const vertices_size_type yDiff = dst_vertex.y - src_vertex.y;
483 const vertices_size_type xAbsDiff = qAbs(xDiff);
484 const vertices_size_type yAbsDiff = qAbs(yDiff);
485 const bool edgeReversed = xDiff < 0 || yDiff < 0;
486
487 if (isReversed != edgeReversed ||
488 (xDiff && binId != HORIZONTAL && binId != HORIZONTAL_REVERSED) ||
489 (yDiff && binId != VERTICAL && binId != VERTICAL_REVERSED) ||
490 xAbsDiff > 1 ||
491 yAbsDiff > 1 ||
492 xAbsDiff == yAbsDiff) {
493
494 return -1;
495 }
496 }
497
498 if (isReversed) {
499 std::swap(src_vertex, dst_vertex);
500 }
501
502 // using direct QRect::contains makes the code 30% slower
503 const int x = src_vertex.x;
504 const int y = src_vertex.y;
505 if (x < rect.x() || x > rect.right() ||
506 y < rect.y() || y > rect.bottom()) {
507 return -1;
508 }
509
510 edges_size_type internalIndex =
511 (src_vertex.x - xOffset) +
512 (src_vertex.y - yOffset) * stride;
513
514 LF_SANITY_ASSERT_RECOVER(internalIndex >= 0 && internalIndex < size) {
515 return -1;
516 }
517
518 return internalIndex + start;
519 }
520
521
523 edges_size_type localOffset = index - start;
524
525 if (localOffset < 0 || localOffset >= size) {
526 return edge_descriptor();
527 }
528
529 const edges_size_type x = localOffset % stride + xOffset;
530 const edges_size_type y = localOffset / stride + yOffset;
531
533 vertex_descriptor dst_vertex;
534
535 switch (binId) {
536 case HORIZONTAL:
538 dst_vertex.x = x + 1;
539 dst_vertex.y = y;
540 dst_vertex.type = vertex_descriptor::NORMAL;
541 break;
542 case VERTICAL:
544 dst_vertex.x = x;
545 dst_vertex.y = y + 1;
546 dst_vertex.type = vertex_descriptor::NORMAL;
547 break;
548 case LABEL_A:
549 case LABEL_A_REVERSED:
550 dst_vertex.type = vertex_descriptor::LABEL_A;
551 break;
552 case LABEL_B:
553 case LABEL_B_REVERSED:
554 dst_vertex.type = vertex_descriptor::LABEL_B;
555 break;
556 }
557
558 if (isReversed) {
559 std::swap(src_vertex, dst_vertex);
560 }
561
562 return std::make_pair(src_vertex, dst_vertex);
563 }
564
571 bool isReversed {false};
572 QRect rect;
573 };
574
576
580
583
584public:
585
586 // Returns the number of vertices in the graph
588 return (m_numVertices);
589 }
590
591 // Returns the number of edges in the graph
592 inline edges_size_type num_edges() const {
593 return (m_numEdges);
594 }
595
596 // Returns the index of [vertex] (See also vertex_at)
598 vertices_size_type vertex_index = -1;
599
600 switch (vertex.type) {
602 vertex_index = vertex.x - m_x + (vertex.y - m_y) * m_width;
603 break;
605 vertex_index = m_numVertices - 2;
606 break;
608 vertex_index = m_numVertices - 1;
609 break;
610 }
611
612 return vertex_index;
613 }
614
615 // Returns the vertex whose index is [vertex_index] (See also
616 // index_of(vertex_descriptor))
619
620 if (vertex_index == m_numVertices - 2) {
622 } else if (vertex_index == m_numVertices - 1) {
624 } else if (vertex_index >= 0) {
625 vertex.x = vertex_index % m_width + m_x;
626 vertex.y = vertex_index / m_width + m_y;
628 }
629
630 return vertex;
631 }
632
633 // Returns the edge whose index is [edge_index] (See also
634 // index_of(edge_descriptor)). NOTE: The index mapping is
635 // dependent upon dimension wrapping.
637
638 int binIndex = 0;
639
640 while (binIndex < m_edgeBins.size() &&
641 !m_edgeBins[binIndex].contains(edge_index)) {
642
643 binIndex++;
644 }
645
646 if (binIndex >= m_edgeBins.size()) {
647 return edge_descriptor();
648 }
649
650 return m_edgeBins[binIndex].edgeAt(edge_index);
651 }
652
653 // Returns the index for [edge] (See also edge_at)
655 edges_size_type index = -1;
656
657 auto it = m_edgeBins.constBegin();
658 for (; it != m_edgeBins.constEnd(); ++it) {
659
660 index = it->indexOf(edge);
661 if (index >= 0) break;
662 }
663
664 return index;
665 }
666
667private:
669 vertices_size_type vacantEdges = 4;
670
671 if (vertex.x == rc.x()) {
672 vacantEdges--;
673 }
674
675 if (vertex.y == rc.y()) {
676 vacantEdges--;
677 }
678
679 if (vertex.x == rc.right()) {
680 vacantEdges--;
681 }
682
683 if (vertex.y == rc.bottom()) {
684 vacantEdges--;
685 }
686
687 return vacantEdges;
688 }
689
690 static inline bool findInRects(const QVector<QRect> &rects, const QPoint &pt) {
691 bool result = false;
692
693 auto it = rects.constBegin();
694 for (; it != rects.constEnd(); ++it) {
695
696 if (it->contains(pt)) {
697 result = true;
698 break;
699 }
700 }
701 return result;
702 }
703public:
704 // Returns the number of out-edges for [vertex]
706 degree_size_type out_edge_count = 0;
707 if (index_of(vertex) < 0) return out_edge_count;
708
709 switch (vertex.type) {
711 out_edge_count = numVacantEdges(vertex, m_mainArea);
712
713 const QPoint pt = QPoint(vertex.x, vertex.y);
714
715 if (m_aLabelArea.contains(pt) && findInRects(m_aLabelRects, pt)) {
716 out_edge_count++;
717 }
718
719 if (m_bLabelArea.contains(pt) && findInRects(m_bLabelRects, pt)) {
720 out_edge_count++;
721 }
722
723 break;
724 }
726 out_edge_count = m_numAEdges;
727 break;
729 out_edge_count = m_numBEdges;
730 break;
731 }
732
733 return (out_edge_count);
734 }
735
736 // Returns an out-edge for [vertex] by index. Indices are in the
737 // range [0, out_degree(vertex)).
739 degree_size_type out_edge_index) const {
740
741 const QPoint pt = QPoint(vertex.x, vertex.y);
742 vertex_descriptor dst_vertex = vertex;
743
744 switch (vertex.type) {
746 if (vertex.x > m_mainArea.x() && !out_edge_index--) {
747 dst_vertex.x--;
748 } else if (vertex.y > m_mainArea.y() && !out_edge_index--) {
749 dst_vertex.y--;
750 } else if (vertex.x < m_mainArea.right() && !out_edge_index--) {
751 dst_vertex.x++;
752 } else if (vertex.y < m_mainArea.bottom() && !out_edge_index--) {
753 dst_vertex.y++;
754 } else if (m_aLabelArea.contains(pt) && findInRects(m_aLabelRects, pt) && !out_edge_index--) {
756 } else if (m_bLabelArea.contains(pt) && findInRects(m_bLabelRects, pt) && !out_edge_index--) {
758 } else {
759 dbgImage << ppVar(vertex) << ppVar(out_edge_index) << ppVar(out_degree(vertex));
760 qFatal("Wrong edge sub-index");
761 }
762 break;
765 dst_vertex = edge.second;
766 break;
767 }
770 dst_vertex = edge.second;
771 break;
772 }
773 }
774
775 return std::make_pair(vertex, dst_vertex);
776 }
777
778public:
779
780 //================
781 // VertexListGraph
782 //================
783
784 friend inline std::pair<typename type::vertex_iterator,
785 typename type::vertex_iterator>
786 vertices(const type& graph) {
787 typedef typename type::vertex_iterator vertex_iterator;
788 typedef typename type::vertex_function vertex_function;
790
791 return (std::make_pair
793 vertex_function(&graph)),
795 vertex_function(&graph))));
796 }
797
798 friend inline typename type::vertices_size_type
799 num_vertices(const type& graph) {
800 return (graph.num_vertices());
801 }
802
803 friend inline typename type::vertex_descriptor
804 vertex(typename type::vertices_size_type vertex_index,
805 const type& graph) {
806
807 return (graph.vertex_at(vertex_index));
808 }
809
810 //===============
811 // IncidenceGraph
812 //===============
813
814 friend inline std::pair<typename type::out_edge_iterator,
817 const type& graph) {
818 typedef typename type::degree_iterator degree_iterator;
821
822 return (std::make_pair
824 out_edge_function(vertex, &graph)),
826 out_edge_function(vertex, &graph))));
827 }
828
829 friend inline typename type::degree_size_type
832 const type& graph) {
833 return (graph.out_degree(vertex));
834 }
835
836 friend inline typename type::edge_descriptor
838 typename type::degree_size_type out_edge_index,
839 const type& graph) {
840 return (graph.out_edge_at(vertex, out_edge_index));
841 }
842
843 //===============
844 // AdjacencyGraph
845 //===============
846
847 friend typename std::pair<typename type::adjacency_iterator,
861
862 //==================
863 // Adjacency Matrix
864 //==================
865
866 friend std::pair<typename type::edge_descriptor, bool>
867 edge (typename type::vertex_descriptor source_vertex,
868 typename type::vertex_descriptor destination_vertex,
869 const type& graph) {
870
871 std::pair<typename type::edge_descriptor, bool> edge_exists =
872 std::make_pair(std::make_pair(source_vertex, destination_vertex), false);
873
874 const edges_size_type index = graph.index_of(edge_exists.first);
875
876 edge_exists.second = index >= 0;
877
878 return edge_exists;
879 }
880
881 //==============
882 // EdgeListGraph
883 //==============
884
885 friend inline typename type::edges_size_type
886 num_edges(const type& graph) {
887 return (graph.num_edges());
888 }
889
890 friend inline typename type::edge_descriptor
891 edge_at(typename type::edges_size_type edge_index,
892 const type& graph) {
893 return (graph.edge_at(edge_index));
894 }
895
896 friend inline std::pair<typename type::edge_iterator,
897 typename type::edge_iterator>
898 edges(const type& graph) {
900 typedef typename type::edge_function edge_function;
901 typedef typename type::edge_iterator edge_iterator;
902
903 return (std::make_pair
905 edge_function(&graph)),
907 edge_function(&graph))));
908 }
909
910 //=============================
911 // Index Property Map Functions
912 //=============================
913
914 friend inline typename type::vertices_size_type
915 get(vertex_index_t,
916 const type& graph,
918
920 LF_SANITY_ASSERT(index >= 0);
921 return index;
922 }
923
924 friend inline typename type::edges_size_type
925 get(edge_index_t,
926 const type& graph,
927 typename type::edge_descriptor edge) {
928
929 type::edges_size_type index = graph.index_of(edge);
930 LF_SANITY_ASSERT(index >= 0);
931 return index;
932 }
933
934 friend inline lazy_fill_graph_index_map<
935 type,
938 get(vertex_index_t, const type& graph) {
940 type,
942 typename type::vertices_size_type>(graph));
943 }
944
945 friend inline lazy_fill_graph_index_map<
946 type,
947 typename type::edge_descriptor,
948 typename type::edges_size_type>
949 get(edge_index_t, const type& graph) {
951 type,
952 typename type::edge_descriptor,
953 typename type::edges_size_type>(graph));
954 }
955
957 typename type::edge_descriptor>
958 get(edge_reverse_t, const type& graph) {
959 Q_UNUSED(graph);
961 typename type::edge_descriptor>());
962 }
963
964 template<typename Graph,
965 typename Descriptor,
966 typename Index>
968
969 template<typename Descriptor>
971};
972
973namespace boost {
974 template <>
975 struct property_map<KisLazyFillGraph, vertex_index_t> {
977 typename graph_traits<KisLazyFillGraph>::vertex_descriptor,
978 typename graph_traits<KisLazyFillGraph>::vertices_size_type> type;
980 };
981
982 template<>
983 struct property_map<KisLazyFillGraph, edge_index_t> {
985 typename graph_traits<KisLazyFillGraph>::edge_descriptor,
986 typename graph_traits<KisLazyFillGraph>::edges_size_type> type;
988 };
989}
990
991namespace boost {
992 template <>
997}
998
1000 const QString type =
1003 v.type == KisLazyFillGraph::vertex_descriptor::LABEL_B ? "label_B" : "<unknown>";
1004
1005 dbg.nospace() << "(" << v.x << ", " << v.y << ", " << type << ")";
1006 return dbg.space();
1007}
1008
1009QDebug operator<<(QDebug dbg, const KisLazyFillGraph::edge_descriptor &e) {
1012
1013 dbg.nospace() << "(" << src << " -> " << dst << ")";
1014 return dbg.space();
1015}
1016
1017#endif /* __KIS_LAZY_FILL_GRAPH_H */
qreal v
KisMagneticGraph::vertex_descriptor target(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
KisMagneticGraph::vertex_descriptor source(typename KisMagneticGraph::edge_descriptor e, KisMagneticGraph g)
transform_iterator< out_edge_function, degree_iterator > out_edge_iterator
vertices_size_type m_aReversedEdgesStart
kis_detail::lazy_fill_graph_edge_at< type > edge_function
transform_iterator< adjacent_vertex_function, degree_iterator > adjacency_iterator
KisLazyFillGraph type
QVector< QRect > m_aLabelRects
friend std::pair< typename type::adjacency_iterator, typename type::adjacency_iterator > adjacent_vertices(typename type::vertex_descriptor vertex, const type &graph)
transform_iterator< edge_function, edge_index_iterator > edge_iterator
friend type::vertex_descriptor vertex(typename type::vertices_size_type vertex_index, const type &graph)
edges_size_type num_edges() const
friend type::vertices_size_type get(vertex_index_t, const type &graph, typename type::vertex_descriptor vertex)
edge_descriptor edge_at(edges_size_type edge_index) const
counting_iterator< vertices_size_type > vertex_index_iterator
QVector< EdgeIndexBin > m_edgeBins
vertex_descriptor vertex_at(vertices_size_type vertex_index) const
vertices_size_type num_vertices() const
friend QDebug operator<<(QDebug dbg, const KisLazyFillGraph::edge_descriptor &e)
static bool findInRects(const QVector< QRect > &rects, const QPoint &pt)
friend type::edges_size_type get(edge_index_t, const type &graph, typename type::edge_descriptor edge)
vertices_size_type m_width
VertexDescriptor vertex_descriptor
kis_detail::lazy_fill_graph_out_edge_at< type > out_edge_function
vertices_size_type m_numEdges
edge_descriptor out_edge_at(vertex_descriptor vertex, degree_size_type out_edge_index) const
edges_size_type index_of(edge_descriptor edge) const
KisLazyFillGraph(const QRect &mainRect, const KisRegion &aLabelRegion, const KisRegion &bLabelRegion)
vertices_size_type m_numBEdges
counting_iterator< degree_size_type > degree_iterator
vertices_size_type m_numVertices
friend std::pair< typename type::vertex_iterator, typename type::vertex_iterator > vertices(const type &graph)
vertices_size_type m_x
friend lazy_fill_graph_reverse_edge_map< typename type::edge_descriptor > get(edge_reverse_t, const type &graph)
friend std::pair< typename type::edge_iterator, typename type::edge_iterator > edges(const type &graph)
degree_size_type out_degree(vertex_descriptor vertex) const
vertices_size_type m_numAEdges
static vertex_descriptor null_vertex()
friend type::vertices_size_type num_vertices(const type &graph)
counting_iterator< edges_size_type > edge_index_iterator
static vertices_size_type numVacantEdges(const vertex_descriptor &vertex, const QRect &rc)
friend lazy_fill_graph_index_map< type, typename type::vertex_descriptor, typename type::vertices_size_type > get(vertex_index_t, const type &graph)
friend lazy_fill_graph_index_map< type, typename type::edge_descriptor, typename type::edges_size_type > get(edge_index_t, const type &graph)
vertices_size_type m_height
friend type::degree_size_type out_degree(typename type::vertex_descriptor vertex, const type &graph)
friend std::pair< typename type::edge_descriptor, bool > edge(typename type::vertex_descriptor source_vertex, typename type::vertex_descriptor destination_vertex, const type &graph)
disallow_parallel_edge_tag edge_parallel_category
vertices_size_type m_bReversedEdgesStart
vertices_size_type index_of(vertex_descriptor vertex) const
friend type::edge_descriptor edge_at(typename type::edges_size_type edge_index, const type &graph)
friend type::edges_size_type num_edges(const type &graph)
friend type::edge_descriptor out_edge_at(typename type::vertex_descriptor vertex, typename type::degree_size_type out_edge_index, const type &graph)
QVector< QRect > m_bLabelRects
friend std::pair< typename type::out_edge_iterator, typename type::out_edge_iterator > out_edges(typename type::vertex_descriptor vertex, const type &graph)
transform_iterator< vertex_function, vertex_index_iterator > vertex_iterator
directed_tag directed_category
kis_detail::lazy_fill_graph_vertex_at< KisLazyFillGraph > vertex_function
kis_detail::lazy_fill_graph_adjacent_vertex_at< type > adjacent_vertex_function
VertexIndex vertices_size_type
std::pair< vertex_descriptor, vertex_descriptor > edge_descriptor
vertices_size_type m_y
QRect boundingRect() const
QVector< QRect > rects() const
#define KIS_ASSERT(cond)
Definition kis_assert.h:33
#define ppVar(var)
Definition kis_debug.h:155
#define dbgImage
Definition kis_debug.h:46
QDebug operator<<(QDebug dbg, const KisLazyFillGraph::vertex_descriptor &v)
#define LF_SANITY_ASSERT_RECOVER(x)
#define LF_SANITY_ASSERT(x)
EdgeIndexBin(const EdgeIndexBin &putAfter, const QRect &_rect, EdgeIndexBinId _binId)
bool contains(const edge_descriptor &edge) const
edges_size_type indexOf(const edge_descriptor &edge) const
edge_descriptor edgeAt(edges_size_type index) const
EdgeIndexBin(edges_size_type _start, const QRect &_rect, EdgeIndexBinId _binId)
bool contains(edges_size_type index) const
bool operator==(const VertexDescriptor &rhs) const
VertexDescriptor(vertices_size_type _x, vertices_size_type _y, VertexType _type=NORMAL)
lazy_fill_graph_index_map< KisLazyFillGraph, typename graph_traits< KisLazyFillGraph >::edge_descriptor, typename graph_traits< KisLazyFillGraph >::edges_size_type > type
lazy_fill_graph_reverse_edge_map< typename graph_traits< KisLazyFillGraph >::edge_descriptor > type
lazy_fill_graph_index_map< KisLazyFillGraph, typename graph_traits< KisLazyFillGraph >::vertex_descriptor, typename graph_traits< KisLazyFillGraph >::vertices_size_type > type
lazy_fill_graph_adjacent_vertex_at(result_type source_vertex, const Graph *graph)
graph_traits< Graph >::vertex_descriptor result_type
graph_traits< Graph >::edge_descriptor result_type
graph_traits< Graph >::vertex_descriptor vertex_descriptor
graph_traits< Graph >::edge_descriptor result_type
lazy_fill_graph_in_edge_at(vertex_descriptor target_vertex, const Graph *graph)
lazy_fill_graph_out_edge_at(vertex_descriptor source_vertex, const Graph *graph)
graph_traits< Graph >::edge_descriptor result_type
graph_traits< Graph >::vertex_descriptor vertex_descriptor
graph_traits< Graph >::vertex_descriptor result_type
readable_property_map_tag category
value_type operator[](key_type key) const
friend Index get(const lazy_fill_graph_index_map< Graph, Descriptor, Index > &index_map, const typename lazy_fill_graph_index_map< Graph, Descriptor, Index >::key_type &key)
lazy_fill_graph_index_map(const Graph &graph)
value_type operator[](const key_type &key) const
friend Descriptor get(const lazy_fill_graph_reverse_edge_map< Descriptor > &rev_map, const typename lazy_fill_graph_reverse_edge_map< Descriptor >::key_type &key)
readable_property_map_tag category