1 #ifndef CGAL_QT_ARCS_GRAPHICS_ITEM_H
2 #define CGAL_QT_ARCS_GRAPHICS_ITEM_H
3 
4 #include <CGAL/Bbox_2.h>
5 #include <CGAL/Qt/PainterOstream.h>
6 #include <CGAL/Qt/GraphicsItem.h>
7 #include <CGAL/Qt/Converter.h>
8 
9 #include <QGraphicsScene>
10 #include <QPainter>
11 #include <QStyleOption>
12 
13 namespace CGAL {
14 namespace Qt {
15 
16 template <typename CK>
17 class ArcsGraphicsItem : public GraphicsItem
18 {
19   std::vector<CGAL::Object>& arcs, &intersections;
20   typedef typename CK::Circle_2 Circle_2;
21   typedef typename CK::Circular_arc_2 Circular_arc_2;
22   typedef typename CK::Circular_arc_point_2 Circular_arc_point_2;
23   typedef typename CK::Line_arc_2 Line_arc_2;
24 
25 public:
26   ArcsGraphicsItem(std::vector<CGAL::Object>& arcs_, std::vector<CGAL::Object>& intersections_);
27 
28   void modelChanged();
29 
30 public:
31   QRectF boundingRect() const;
32 
33   void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
34 
35 
intersectionsPen()36   const QPen& intersectionsPen() const
37   {
38     return intersections_pen;
39   }
40 
inputPen()41   const QPen& inputPen() const
42   {
43     return input_pen;
44   }
45 
setIntersectionsPen(const QPen & pen)46   void setIntersectionsPen(const QPen& pen)
47   {
48     intersections_pen = pen;
49   }
50 
setInputPen(const QPen & pen)51   void setInputPen(const QPen& pen)
52   {
53     input_pen = pen;
54   }
55 
56 protected:
57   void updateBoundingBox();
58 
59   QPainter* m_painter;
60   PainterOstream<CK> painterostream;
61 
62   QRectF bounding_rect;
63 
64   QPen intersections_pen;
65   QPen input_pen;
66   Converter<CK> convert;
67 };
68 
69 
70 template <typename CK>
ArcsGraphicsItem(std::vector<CGAL::Object> & arcs_,std::vector<CGAL::Object> & intersections_)71 ArcsGraphicsItem<CK>::ArcsGraphicsItem(std::vector<CGAL::Object>& arcs_, std::vector<CGAL::Object>& intersections_)
72   :  arcs(arcs_), intersections(intersections_), painterostream(nullptr)
73 {
74   setIntersectionsPen(QPen(::Qt::red, 3.));
75   if(arcs.empty()){
76     this->hide();
77   }
78   updateBoundingBox();
79   setZValue(3);
80 }
81 
82 template <typename CK>
83 QRectF
boundingRect()84 ArcsGraphicsItem<CK>::boundingRect() const
85 {
86   return bounding_rect;
87 }
88 
89 
90 
91 template <typename CK>
92 void
paint(QPainter * painter,const QStyleOptionGraphicsItem *,QWidget *)93 ArcsGraphicsItem<CK>::paint(QPainter *painter,
94                                     const QStyleOptionGraphicsItem *,
95                                     QWidget * )
96 {
97   painter->setPen(this->inputPen());
98   painterostream = PainterOstream<CK>(painter);
99 
100   for(std::vector<CGAL::Object>::iterator it = arcs.begin(); it != arcs.end(); ++it){
101     Circular_arc_2 ca;
102     Line_arc_2 la;
103     if(assign(ca, *it)){
104       painterostream << ca;
105     } else if(assign(la, *it)){
106       painterostream << la;
107     }
108   }
109 
110 
111   painter->setPen(this->intersectionsPen());
112   painterostream = PainterOstream<CK>(painter);
113   for(std::vector<CGAL::Object>::iterator it = intersections.begin(); it != intersections.end(); ++it){
114     std::pair<Circular_arc_point_2,unsigned> cap_ui;
115     Circular_arc_2 ca;
116     Line_arc_2 la;
117 
118     if(assign(cap_ui, *it)){
119       QTransform matrix = painter->worldTransform();
120       painter->resetTransform();
121       painter->drawPoint(matrix.map(convert(cap_ui.first)));
122       painter->setWorldTransform(matrix);
123     }if(assign(ca, *it)){
124       painterostream << ca;
125     } else if(assign(la, *it)){
126       painterostream << la;
127     }
128   }
129 }
130 
131 template <typename CK>
132 void
updateBoundingBox()133 ArcsGraphicsItem<CK>::updateBoundingBox()
134 {
135   bounding_rect = QRectF(0,0,100, 100);
136   Bbox_2 bb;
137   bool initialized = false;
138   for(std::vector<CGAL::Object>::iterator it = arcs.begin(); it != arcs.end(); ++it){
139     Circular_arc_2 ca;
140     Line_arc_2 la;
141     if(assign(ca, *it)){
142       if(initialized){
143         bb = bb + ca.supporting_circle().bbox();
144       } else {
145         initialized = true;
146         bb = ca.supporting_circle().bbox();
147       }
148     } else if(assign(la, *it)){
149       if(initialized){
150         bb = bb + la.bbox();
151       } else {
152         initialized = true;
153         bb = la.bbox();
154       }
155     }
156   }
157 
158   prepareGeometryChange();
159   bounding_rect = convert(bb);
160 }
161 
162 
163 template <typename CK>
164 void
modelChanged()165 ArcsGraphicsItem<CK>::modelChanged()
166 {
167   if((arcs.empty()) ){
168     this->hide();
169   } else if((! arcs.empty()) && (! this->isVisible())){
170     this->show();
171   }
172   updateBoundingBox();
173   update();
174 }
175 
176 
177 } // namespace Qt
178 } // namespace CGAL
179 
180 #endif // CGAL_QT_ARCS_GRAPHICS_ITEM_H
181