1 // Copyright (c) 2008  GeometryFactory Sarl (France).
2 // All rights reserved.
3 //
4 // This file is part of CGAL (www.cgal.org).
5 //
6 // $URL: https://github.com/CGAL/cgal/blob/v5.3/Hyperbolic_triangulation_2/demo/Hyperbolic_triangulation_2/include/internal/Qt/TriangulationGraphicsItemWithColorInfo.h $
7 // $Id: TriangulationGraphicsItemWithColorInfo.h 0779373 2020-03-26T13:31:46+01:00 Sébastien Loriot
8 // SPDX-License-Identifier: GPL-3.0-or-later OR LicenseRef-Commercial
9 //
10 //
11 // Author(s)     : Andreas Fabri <Andreas.Fabri@geometryfactory.com>
12 //                 Laurent Rineau <Laurent.Rineau@geometryfactory.com>
13 
14 #ifndef CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
15 #define CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
16 
17 #include <CGAL/Bbox_2.h>
18 #include <CGAL/apply_to_range.h>
19 #include <CGAL/Qt/PainterOstream.h>
20 #include <CGAL/Qt/GraphicsItem.h>
21 #include <CGAL/Qt/Converter.h>
22 
23 #include <QGraphicsScene>
24 #include <QPainter>
25 #include <QStyleOption>
26 
27 namespace CGAL {
28 namespace Qt {
29 
30 template <typename T>
31 class TriangulationGraphicsItem : public GraphicsItem
32 {
33   typedef typename T::Geom_traits Geom_traits;
34 public:
35   TriangulationGraphicsItem(T* t_);
36 
37   void modelChanged();
38 
39 public:
40 
41   QRectF boundingRect() const;
42 
43   void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
44 
45   virtual void operator()(typename T::Face_handle fh);
46 
verticesPen()47   const QPen& verticesPen() const
48   {
49     return vertices_pen;
50   }
51 
edgesPen()52   const QPen& edgesPen() const
53   {
54     return edges_pen;
55   }
56 
setVerticesPen(const QPen & pen)57   void setVerticesPen(const QPen& pen)
58   {
59     vertices_pen = pen;
60   }
61 
setEdgesPen(const QPen & pen)62   void setEdgesPen(const QPen& pen)
63   {
64     edges_pen = pen;
65   }
66 
visibleVertices()67   bool visibleVertices() const
68   {
69     return visible_vertices;
70   }
71 
setVisibleVertices(const bool b)72   void setVisibleVertices(const bool b)
73   {
74     visible_vertices = b;
75     update();
76   }
77 
visibleEdges()78   bool visibleEdges() const
79   {
80     return visible_edges;
81   }
82 
setVisibleEdges(const bool b)83   void setVisibleEdges(const bool b)
84   {
85     visible_edges = b;
86     update();
87   }
88 
89 protected:
90   virtual void drawAll(QPainter *painter);
91   void paintVertices(QPainter *painter);
92   void paintOneVertex(const typename T::Point& point);
93   virtual void paintVertex(typename T::Vertex_handle vh);
94   void updateBoundingBox();
95 
96   T * t;
97   QPainter* m_painter;
98   PainterOstream<Geom_traits> painterostream;
99 
100   typename T::Vertex_handle vh;
101   typename T::Point p;
102   CGAL::Bbox_2 bb;
103   bool bb_initialized;
104   QRectF bounding_rect;
105 
106   QPen vertices_pen;
107   QPen edges_pen;
108   bool visible_edges;
109   bool visible_vertices;
110 };
111 
112 
113 template <typename T>
TriangulationGraphicsItem(T * t_)114 TriangulationGraphicsItem<T>::TriangulationGraphicsItem(T * t_)
115   :  t(t_), painterostream(0),
116      bb(0,0,0,0), bb_initialized(false),
117      visible_edges(true), visible_vertices(true)
118 {
119   setVerticesPen(QPen(::Qt::red, 3.));
120   if(t->number_of_vertices() == 0){
121     this->hide();
122   }
123   updateBoundingBox();
124   setZValue(3);
125 }
126 
127 template <typename T>
128 QRectF
boundingRect()129 TriangulationGraphicsItem<T>::boundingRect() const
130 {
131   return bounding_rect;
132 }
133 
134 
135 template <typename T>
136 void
operator()137 TriangulationGraphicsItem<T>::operator()(typename T::Face_handle fh)
138 {
139   if(visible_edges) {
140     for(int i=0; i<3; i++) {
141       if(fh < fh->neighbor(i) || t->is_infinite(fh->neighbor(i))){
142         m_painter->setPen(this->edgesPen());
143         painterostream << t->segment(fh,i);
144       }
145     }
146   }
147   if(visible_vertices) {
148     for(int i=0; i<3; i++) {
149       paintVertex(fh->vertex(i));
150     }
151   }
152 }
153 
154 template <typename T>
155 void
drawAll(QPainter * painter)156 TriangulationGraphicsItem<T>::drawAll(QPainter *painter)
157 {
158   //delete
159   QPen temp = painter->pen();
160   QPen old = temp;
161   temp.setWidthF(/*0.0035*/0.0045);
162   painter->setPen(temp);
163   //
164 
165   painterostream = PainterOstream<Geom_traits>(painter);
166 
167   if(visibleEdges()) {
168     for(typename T::Finite_edges_iterator eit = t->finite_edges_begin();
169         eit != t->finite_edges_end();
170         ++eit){
171       painterostream << t->segment(*eit);
172     }
173   }
174 
175   //delete
176   painter->setPen(old);
177   //
178 
179   paintVertices(painter);
180 }
181 
182 template <typename T>
183 void
paintVertices(QPainter * painter)184 TriangulationGraphicsItem<T>::paintVertices(QPainter *painter)
185 {
186   if(visibleVertices()) {
187     Converter<Geom_traits> convert;
188 
189     painter->setPen(verticesPen());
190     QTransform matrix = painter->worldTransform();
191     painter->resetTransform();
192     for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
193         it != t->finite_vertices_end();
194         it++){
195 
196       // draw vertices with color storing in their info
197       if(it->info().getColor() == 0) {
198         painter->setPen(QPen(::Qt::red, 3.));
199       }
200 
201       if(it->info().getColor() == 1) {
202         painter->setPen(QPen(::Qt::green, 3.));
203       }
204 
205       if(it->info().getColor() == 2) {
206         painter->setPen(QPen(::Qt::cyan, 3.));
207       }
208 
209       if(it->info().getColor() == 3) {
210         painter->setPen(QPen(::Qt::magenta, 3.));
211       }
212 
213       if(it->info().getColor() == 6) {
214         painter->setPen(QPen(::Qt::yellow, 3.));
215       }
216 
217       if(it->info().getColor() == 5) {
218         // brown
219         painter->setPen(QPen(QColor(139, 69, 19), 3.));
220       }
221 
222       if(it->info().getColor() == 4) {
223         painter->setPen(QPen(::Qt::blue, 3.));
224       }
225 
226 
227       if(it->info().getColor() == 7) {
228         // orange
229         QColor orange = QColor(255, 165, 0);
230         painter->setPen(QPen(orange, 3.));
231       }
232 
233       if(it->info().getColor() == 8) {
234         // dark green
235         QColor blue = QColor(0, 102, 51);
236         painter->setPen(QPen(blue, 3.));
237       }
238 
239       if(it->info().getColor() == 9) {
240         // purple
241         QColor blue = QColor(102, 0, 102);
242         painter->setPen(QPen(blue, 3.));
243       }
244 
245       if(it->info().getColor() == 10) {
246         // close to blue
247         QColor blue = QColor(131, 111, 255);
248         painter->setPen(QPen(blue, 3.));
249       }
250 
251       //
252 
253       // delete
254       QPen temp = painter->pen();
255       QPen old = temp;
256       temp.setWidth(9);
257 
258       double px = to_double(t->point(it).x());
259       double py = to_double(t->point(it).y());
260       double dist = px*px + py*py;
261       if(dist > 0.25) {
262         temp.setWidth(8);//6
263       }
264       if(dist > 0.64) {
265         temp.setWidth(7);//5
266       }
267       if(dist > 0.81) {
268         temp.setWidth(5);//3
269       }
270       if(dist > 0.92) {
271         temp.setWidth(4);//3
272       }
273       if(dist > 0.98) {
274         temp.setWidth(3);//3
275       }
276       //painter->setPen(temp);
277 
278       QPointF point = matrix.map(convert(t->point(it)));
279       painter->drawPoint(point);
280 
281       painter->setPen(old);
282 
283       /*
284       QBrush temp = painter->brush();
285       QBrush old = temp;
286       temp.setColor(painter->pen().color());
287 
288       painter->setBrush(temp);
289 
290       painter->drawEllipse(point, 10, 10);
291 
292       painter->setBrush(old);
293        */
294     }
295   }
296 }
297 
298 template <typename T>
299 void
paintOneVertex(const typename T::Point & point)300 TriangulationGraphicsItem<T>::paintOneVertex(const typename T::Point& point)
301 {
302   Converter<Geom_traits> convert;
303 
304   m_painter->setPen(this->verticesPen());
305   QTransform matrix = m_painter->worldTransform();
306   m_painter->resetTransform();
307   m_painter->drawPoint(matrix.map(convert(point)));
308   m_painter->setWorldTransform(matrix);
309 }
310 
311 template <typename T>
312 void
paintVertex(typename T::Vertex_handle vh)313 TriangulationGraphicsItem<T>::paintVertex(typename T::Vertex_handle vh)
314 {
315   Converter<Geom_traits> convert;
316   m_painter->setPen(this->verticesPen());
317 
318   QTransform matrix = m_painter->worldTransform();
319   m_painter->resetTransform();
320   m_painter->drawPoint(matrix.map(convert(t->point(vh))));
321   m_painter->setWorldTransform(matrix);
322 }
323 
324 template <typename T>
325 void
paint(QPainter * painter,const QStyleOptionGraphicsItem * option,QWidget *)326 TriangulationGraphicsItem<T>::paint(QPainter *painter,
327                                     const QStyleOptionGraphicsItem *option,
328                                     QWidget * /*widget*/)
329 {
330   painter->setPen(this->edgesPen());
331 //   painter->drawRect(boundingRect());
332   if(t->dimension()<2 || option->exposedRect.contains(boundingRect())) {
333     drawAll(painter);
334   } else {
335     m_painter = painter;
336     painterostream = PainterOstream<Geom_traits>(painter);
337     CGAL::apply_to_range (*t,
338                           typename T::Point(option->exposedRect.left(),
339                                             option->exposedRect.bottom()),
340                           typename T::Point(option->exposedRect.right(),
341                                             option->exposedRect.top()),
342                           *this);
343   }
344 }
345 
346 // We let the bounding box only grow, so that when vertices get removed
347 // the maximal bbox gets refreshed in the GraphicsView
348 template <typename T>
349 void
updateBoundingBox()350 TriangulationGraphicsItem<T>::updateBoundingBox()
351 {
352   prepareGeometryChange();
353   if(t->number_of_vertices() == 0){
354     bb = Bbox_2(0,0,0,0);
355     bb_initialized = false;
356     return;
357   } else if(! bb_initialized){
358     bb = t->point(t->finite_vertices_begin()).bbox();
359     bb_initialized = true;
360   }
361 
362   if(t->dimension() <2){
363     for(typename T::Finite_vertices_iterator it = t->finite_vertices_begin();
364         it != t->finite_vertices_end();
365         ++it){
366       bb = bb + t->point(it).bbox();
367     }
368   } else {
369     typename T::Vertex_handle inf = t->infinite_vertex();
370     typename T::Vertex_circulator vc = t->incident_vertices(inf), done(vc);
371     do {
372       bb = bb + t->point(vc).bbox();
373       ++vc;
374     } while(vc != done);
375   }
376   bounding_rect = QRectF(bb.xmin(),
377                          bb.ymin(),
378                          bb.xmax()-bb.xmin(),
379                          bb.ymax()-bb.ymin());
380 }
381 
382 
383 template <typename T>
384 void
modelChanged()385 TriangulationGraphicsItem<T>::modelChanged()
386 {
387   if((t->number_of_vertices() == 0)){
388     this->hide();
389   } else if((t->number_of_vertices() > 0) && (! this->isVisible())){
390     this->show();
391   }
392   updateBoundingBox();
393   update();
394 }
395 
396 
397 } // namespace Qt
398 } // namespace CGAL
399 
400 #endif // CGAL_QT_TRIANGULATION_GRAPHICS_ITEM_H
401