1 #include <CGAL/Three/Scene_item_rendering_helper.h>
2 #include <QSlider>
3 #include <CGAL/Three/Viewer_interface.h>
4 #include <CGAL/Three/Triangle_container.h>
5 #include <CGAL/Three/Edge_container.h>
6 #include <CGAL/Three/Point_container.h>
7 #include <CGAL/Sqrt_extension.h>
8 #include <QWidgetAction>
9 #include <QMenu>
10 #include <QApplication>
11 #include <QThreadPool>
12
13 using namespace CGAL::Three;
14
15 struct PRIV{
PRIVPRIV16 PRIV(Scene_item_rendering_helper* item)
17 : item(item),
18 is_bbox_computed(false),
19 is_diag_bbox_computed(false),
20 _diag_bbox(0),
21 alphaSlider(nullptr),
22 are_buffers_filled(false)
23 {}
24
~PRIVPRIV25 ~PRIV()
26 {
27 if(alphaSlider)
28 delete alphaSlider;
29
30 for(std::size_t i = 0; i < triangle_containers.size(); ++i)
31 {
32 delete triangle_containers[i];
33 }
34 for(std::size_t i = 0; i < edge_containers.size(); ++i)
35 {
36 delete edge_containers[i];
37 }
38 for(std::size_t i = 0; i < point_containers.size(); ++i)
39 {
40 delete point_containers[i];
41 }
42 }
43
44 Scene_item_rendering_helper* item;
45 Scene_item::Bbox _bbox;
46 bool is_bbox_computed;
47 bool is_diag_bbox_computed;
48 double _diag_bbox;
49 QSlider* alphaSlider;
50 bool are_buffers_filled;
51 std::map<CGAL::Three::Viewer_interface*, bool> isinit;
52 QMap<CGAL::Three::Viewer_interface*, bool> buffers_init;
53 std::vector<CGAL::Three::Triangle_container*> triangle_containers;
54 std::vector<CGAL::Three::Edge_container*> edge_containers;
55 std::vector<CGAL::Three::Point_container*> point_containers;
56
57 void compute_diag_bbox();
58 };
59
Scene_item_rendering_helper()60 Scene_item_rendering_helper::Scene_item_rendering_helper()
61 :Scene_item(0,0),
62 priv(new PRIV(this)){}
63
~Scene_item_rendering_helper()64 Scene_item_rendering_helper::~Scene_item_rendering_helper()
65 {
66 if(priv)
67 delete priv;
68 }
69
diagonalBbox() const70 double Scene_item_rendering_helper::diagonalBbox() const {
71 if(!priv->is_diag_bbox_computed)
72 priv->compute_diag_bbox();
73 priv->is_diag_bbox_computed = true;
74 return priv->_diag_bbox;
75 }
76
compute_diag_bbox()77 void PRIV::compute_diag_bbox()
78 {
79 const Scene_item::Bbox& b_box = item->bbox();
80 _diag_bbox = CGAL::approximate_sqrt(
81 CGAL::square(b_box.xmax() - b_box.xmin())
82 + CGAL::square(b_box.ymax() - b_box.ymin())
83 + CGAL::square(b_box.zmax() - b_box.zmin())
84 );
85 }
86
alpha() const87 float Scene_item_rendering_helper::alpha() const
88 {
89 if(!priv->alphaSlider)
90 return 1.0f;
91 return (float)priv->alphaSlider->value() / 255.0f;
92 }
93
initGL(CGAL::Three::Viewer_interface * viewer) const94 void Scene_item_rendering_helper::initGL(CGAL::Three::Viewer_interface* viewer) const
95 {
96 if(!priv->alphaSlider)
97 {
98 priv->alphaSlider = new QSlider(::Qt::Horizontal);
99 priv->alphaSlider->setMinimum(0);
100 priv->alphaSlider->setMaximum(255);
101 priv->alphaSlider->setValue(255);
102 }
103
104 Q_FOREACH(Triangle_container* tc, priv->triangle_containers)
105 {
106 if(!tc->isGLInit(viewer))
107 tc->initGL(viewer);
108 }
109 Q_FOREACH(Edge_container* ec, priv->edge_containers)
110 {
111 if(!ec->isGLInit(viewer))
112 ec->initGL(viewer);
113 }
114 Q_FOREACH(Point_container* pc, priv->point_containers)
115 {
116 if(!pc->isGLInit(viewer))
117 pc->initGL(viewer);
118 }
119 if(!getBuffersFilled())
120 {
121 Gl_data_names flags;
122 flags = (ALL);
123 processData(flags);
124 }
125 priv->isinit[viewer] = true;
126 }
127
processData(Gl_data_names) const128 void Scene_item_rendering_helper::processData(Gl_data_names )const
129 {
130 computeElements();
131 priv->are_buffers_filled = true;
132 }
133
134
contextMenu()135 QMenu* Scene_item_rendering_helper::contextMenu()
136 {
137 QMenu* resMenu = Scene_item::contextMenu();
138 bool prop = property("menu_changed").toBool();
139 if(!prop)
140 {
141 QMenu *container = new QMenu(tr("Alpha value"));
142 QWidgetAction *sliderAction = new QWidgetAction(nullptr);
143
144 sliderAction->setDefaultWidget(priv->alphaSlider);
145 container->addAction(sliderAction);
146 resMenu->addMenu(container);
147 setProperty("menu_changed", true);
148 }
149 return resMenu;
150 }
151
setAlpha(int alpha)152 void Scene_item_rendering_helper::setAlpha(int alpha)
153 {
154 if(!priv->alphaSlider)
155 {
156 priv->alphaSlider = new QSlider(::Qt::Horizontal);
157 priv->alphaSlider->setMinimum(0);
158 priv->alphaSlider->setMaximum(255);
159 priv->alphaSlider->setValue(255);
160 }
161 priv->alphaSlider->setValue(alpha);
162 redraw();
163 }
164
bbox() const165 Scene_item::Bbox Scene_item_rendering_helper::bbox() const {
166 if(!priv->is_bbox_computed)
167 compute_bbox();
168 priv->is_bbox_computed = true;
169 return priv->_bbox;
170 }
171
isInit(CGAL::Three::Viewer_interface * viewer) const172 bool Scene_item_rendering_helper::isInit(CGAL::Three::Viewer_interface* viewer)const
173 {
174 if(priv->isinit.find(viewer) != priv->isinit.end())
175 return priv->isinit[viewer];
176 return false;
177 }
178
alphaSlider()179 QSlider* Scene_item_rendering_helper::alphaSlider() { return priv->alphaSlider; }
180
setBbox(Bbox b) const181 void Scene_item_rendering_helper::setBbox(Bbox b)const { priv->_bbox = b; }
182
getTriangleContainer(std::size_t id) const183 Triangle_container* Scene_item_rendering_helper::getTriangleContainer(std::size_t id)const
184 {
185 return priv->triangle_containers[id];
186 }
187
getEdgeContainer(std::size_t id) const188 Edge_container* Scene_item_rendering_helper::getEdgeContainer(std::size_t id)const
189 {
190 return priv->edge_containers[id];
191 }
192
getPointContainer(std::size_t id) const193 Point_container* Scene_item_rendering_helper::getPointContainer(std::size_t id)const
194 {
195 return priv->point_containers[id];
196 }
197
198
setTriangleContainer(std::size_t id,Triangle_container * tc)199 void Scene_item_rendering_helper::setTriangleContainer(std::size_t id,
200 Triangle_container* tc)
201 {
202 if(priv->triangle_containers.size() <= id)
203 {
204 priv->triangle_containers.resize(id+1, nullptr);
205 }
206 if(priv->triangle_containers[id])
207 delete priv->triangle_containers[id];
208 priv->triangle_containers[id] = tc;
209 }
210
setEdgeContainer(std::size_t id,Edge_container * ec)211 void Scene_item_rendering_helper::setEdgeContainer(std::size_t id,
212 Edge_container* ec)
213 {
214 if(priv->edge_containers.size() <= id)
215 {
216 priv->edge_containers.resize(id+1, nullptr);
217 }
218 if(priv->edge_containers[id])
219 delete priv->edge_containers[id];
220 priv->edge_containers[id] = ec;
221 }
222
setPointContainer(std::size_t id,Point_container * pc)223 void Scene_item_rendering_helper::setPointContainer(std::size_t id,
224 Point_container* pc)
225 {
226 if(priv->point_containers.size() <= id)
227 {
228 priv->point_containers.resize(id+1, nullptr);
229 }
230 if(priv->point_containers[id])
231 delete priv->point_containers[id];
232 priv->point_containers[id] = pc;
233 }
234
235
setBuffersFilled(bool b) const236 void Scene_item_rendering_helper::setBuffersFilled(bool b) const
237 {
238 priv->are_buffers_filled = b;
239 }
240
getBuffersFilled() const241 bool Scene_item_rendering_helper::getBuffersFilled()const
242 {
243 return priv->are_buffers_filled;
244 }
245
getBuffersInit(Viewer_interface * viewer) const246 bool Scene_item_rendering_helper::getBuffersInit(Viewer_interface* viewer) const
247 {
248 return priv->buffers_init[viewer];
249 }
250
setBuffersInit(Viewer_interface * viewer,bool val) const251 void Scene_item_rendering_helper::setBuffersInit(Viewer_interface* viewer, bool val)const
252 {
253 priv->buffers_init[viewer] = val;
254 }
255
removeViewer(Viewer_interface * viewer)256 void Scene_item_rendering_helper::removeViewer(Viewer_interface *viewer)
257 {
258 Q_FOREACH(Triangle_container* tc, priv->triangle_containers)
259 {
260 tc->removeViewer(viewer);
261 }
262 Q_FOREACH(Edge_container* ec, priv->edge_containers)
263 {
264 ec->removeViewer(viewer);
265 }
266 Q_FOREACH(Point_container* pc, priv->point_containers)
267 {
268 pc->removeViewer(viewer);
269 }
270 }
271
newViewer(Viewer_interface * viewer)272 void Scene_item_rendering_helper::newViewer(Viewer_interface *viewer)
273 {
274 viewer->makeCurrent();
275 Q_FOREACH(Triangle_container* tc, priv->triangle_containers)
276 {
277 if(!tc->isGLInit(viewer))
278 tc->initGL(viewer);
279 }
280 Q_FOREACH(Edge_container* ec, priv->edge_containers)
281 {
282 if(!ec->isGLInit(viewer))
283 ec->initGL(viewer);
284 }
285 Q_FOREACH(Point_container* pc, priv->point_containers)
286 {
287 if(!pc->isGLInit(viewer))
288 pc->initGL(viewer);
289 }
290 //call function that recomputes vao binding
291 initializeBuffers(viewer);
292 }
293