1 //#define CGAL_PMP_REMESHING_VERBOSE
2
3
4 #include "Scene_edit_polyhedron_item.h"
5 #include "Scene_spheres_item.h"
6 #include <CGAL/Three/Three.h>
7 #include <CGAL/Three/Viewer_interface.h>
8 #include <CGAL/Three/Triangle_container.h>
9 #include <CGAL/Three/Edge_container.h>
10 #include <CGAL/Three/Point_container.h>
11 #include <CGAL/Qt/constraint.h>
12 #include <algorithm>
13 #include <QElapsedTimer>
14
15 #include <QApplication>
16
17 #include <CGAL/Polygon_mesh_processing/border.h>
18 #include <CGAL/Polygon_mesh_processing/remesh.h>
19 using namespace CGAL::Three;
20 typedef Viewer_interface Vi;
21 typedef Triangle_container Tc;
22 typedef Edge_container Ec;
23 typedef Point_container Pc;
24
25 struct Scene_edit_polyhedron_item_priv
26 {
Scene_edit_polyhedron_item_privScene_edit_polyhedron_item_priv27 Scene_edit_polyhedron_item_priv(Scene_surface_mesh_item* sm_item, Ui::DeformMesh* ui_widget, QMainWindow* mw, Scene_edit_polyhedron_item* parent)
28 : ui_widget(ui_widget),
29 sm_item(sm_item),
30 is_rot_free(true),
31 own_poly_item(true),
32 k_ring_selector(sm_item, mw, Scene_facegraph_item_k_ring_selection::Active_handle::VERTEX, true)
33 {
34 item = parent;
35 nb_ROI = 0;
36 nb_control = 0;
37 nb_axis = 0;
38 nb_bbox = 0;
39 spheres = nullptr;
40 spheres_ctrl = nullptr;
41 need_change = false;
42 }
~Scene_edit_polyhedron_item_privScene_edit_polyhedron_item_priv43 ~Scene_edit_polyhedron_item_priv()
44 {
45 if(sm_item)
46 delete deform_sm_mesh;
47 if (own_poly_item)
48 {
49 if(sm_item)
50 delete sm_item;
51 }
52 }
53
54 template<typename Mesh>
55 void remesh(Mesh* mesh);
56 template<typename Mesh>
57 void deform(Mesh* mesh);
58 template<typename Mesh>
59 void expand_or_reduce(int, Mesh*);
60 template<typename Mesh>
61 void compute_normals_and_vertices(Mesh *mesh);
62 void compute_bbox(const CGAL::Three::Scene_interface::Bbox&);
63 void reset_drawing_data();
64 void init_values();
65 template<typename Mesh>
66 void pivoting_begin(Mesh* mesh);
67 template<typename Mesh>
68 void pivoting_end(Mesh* mesh);
69 template<typename Mesh>
70 void read_roi(const char* file_name, Mesh* mesh);
71 void draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, CGAL::qglviewer::ManipulatedFrame* frame, const CGAL::qglviewer::Vec ¢er) const;
72 template<typename Mesh, typename M_Deform_mesh>
73 void apply_reset_drawing_data(Mesh* mesh, M_Deform_mesh* m_deform_mesh);
74 template<typename Mesh>
75 void delete_ctrl_vertices_group(Mesh *mesh, bool create_new = true);
76
77 enum Face_names
78 {
79 Facets=0,
80 Frame_plane
81 };
82 enum Edge_names{
83 Edges=0,
84 BBox,
85 Axis
86 };
87 enum Point_names{
88 Roi_points=0,
89 Control_points
90 };
91
92 Ui::DeformMesh* ui_widget;
93 Scene_surface_mesh_item* sm_item;
94 bool need_change;
95 // For drawing
96 mutable std::vector<GLfloat> positions;
97 mutable std::vector<unsigned int> tris;
98 mutable std::vector<unsigned int> _edges;
99 mutable std::vector<GLfloat> color_lines;
100 mutable std::vector<GLfloat> ROI_points;
101 mutable std::vector<GLfloat> control_points;
102 mutable std::vector<GLfloat> control_color;
103 mutable std::vector<GLfloat> normals;
104 mutable std::vector<GLfloat> pos_bbox;
105 mutable std::vector<GLfloat> pos_axis;
106 mutable std::vector<unsigned int> plane_idx;
107 mutable std::vector<GLfloat> pos_frame_plane;
108 mutable std::size_t nb_ROI;
109 mutable std::size_t nb_control;
110 mutable std::size_t nb_axis;
111 mutable std::size_t nb_bbox;
112 mutable Scene_spheres_item* spheres;
113 mutable Scene_spheres_item* spheres_ctrl;
114 mutable QOpenGLBuffer *in_bu;
115
116 Deform_sm_mesh* deform_sm_mesh;
117 typedef std::list<Control_vertices_data<SMesh> > Ctrl_vertices_sm_group_data_list;
118 Ctrl_vertices_sm_group_data_list::iterator sm_active_group;
119 Ctrl_vertices_sm_group_data_list sm_ctrl_vertex_frame_map;
120
121 double length_of_axis; // for drawing axis at a group of control vertices
122
123 // by interleaving 'viewer's events (check constructor), keep followings:
124 Mouse_keyboard_state_deformation state;
125
126 //For constraint rotation
127 CGAL::qglviewer::LocalConstraint rot_constraint;
128 bool is_rot_free;
129
130 bool own_poly_item; //indicates if the poly_item should be deleted by the destructor
131 Scene_facegraph_item_k_ring_selection k_ring_selector;
132 Scene_edit_polyhedron_item *item;
133
134 }; //end Scene_edit_polyhedron_item_priv
135
136 typedef Scene_edit_polyhedron_item_priv Priv;
137
138 struct Facegraph_selector
139 {
140
Facegraph_selectorFacegraph_selector141 Facegraph_selector()
142 :d(nullptr){} //used for the const functions
143
144 Scene_edit_polyhedron_item_priv* d;
Facegraph_selectorFacegraph_selector145 Facegraph_selector(Scene_edit_polyhedron_item_priv* d)
146 :d(d){}
147
148 ////Deform_mesh/////
get_deform_meshFacegraph_selector149 Deform_sm_mesh* get_deform_mesh(SMesh*)
150 {
151 return d->deform_sm_mesh;
152 }
153
set_deform_meshFacegraph_selector154 void set_deform_mesh(SMesh*, Deform_sm_mesh *dm)
155 {
156 d->deform_sm_mesh = dm;
157 }
158
159 ////Items management/////
160
invalidate_aabb_treeFacegraph_selector161 void invalidate_aabb_tree(SMesh*)
162 {
163 d->sm_item->invalidate_aabb_tree();
164 }
165
update_idsFacegraph_selector166 void update_ids(SMesh*, bool )
167 {
168 d->sm_item->polyhedron()->collect_garbage();
169 }
170
171 ////ctrl_groups/////
172
get_active_groupFacegraph_selector173 Ctrl_vertices_sm_group_data_list::iterator& get_active_group(SMesh*)
174 {
175 return d->sm_active_group;
176 }
177
178
179
get_ctrl_vertex_frame_mapFacegraph_selector180 Ctrl_vertices_sm_group_data_list& get_ctrl_vertex_frame_map(SMesh*)
181 {
182 return d->sm_ctrl_vertex_frame_map;
183 }
184
185
186
187
188 //const functions
189
get_ctrl_vertex_frame_mapFacegraph_selector190 Ctrl_vertices_sm_group_data_list& get_ctrl_vertex_frame_map(SMesh*, Scene_edit_polyhedron_item_priv* d)const
191 {
192 return d->sm_ctrl_vertex_frame_map;
193 }
194
195
get_active_groupFacegraph_selector196 Ctrl_vertices_sm_group_data_list::iterator& get_active_group(SMesh*, Scene_edit_polyhedron_item_priv* d)const
197 {
198 return d->sm_active_group;
199 }
200
201 };
202
init_values()203 void Scene_edit_polyhedron_item_priv::init_values()
204 {
205 length_of_axis = (CGAL::sqrt((item->bbox().xmax()-item->bbox().xmin())*
206 (item->bbox().xmax()-item->bbox().xmin()) +
207 (item->bbox().ymax()-item->bbox().ymin())*
208 (item->bbox().ymax()-item->bbox().ymin()) +
209 (item->bbox().zmax()-item->bbox().zmin())*
210 (item->bbox().zmax()-item->bbox().zmin()))) / 15.0;
211
212 // interleave events of viewer (there is only one viewer)
213 Three::mainViewer()->installEventFilter(item);
214
215 // create an empty group of control vertices for starting
216 item->create_ctrl_vertices_group();
217
218 // Required for drawing functionality
219 reset_drawing_data();
220
221 //Generates an integer which will be used as ID for each buffer
222
223 ui_widget->remeshing_iterations_spinbox->setValue(1);
224
225 ui_widget->remeshing_edge_length_spinbox->setValue(length_of_axis);
226 ui_widget->remeshing_edge_length_spinbox->setDisabled(true);
227 ui_widget->remeshingEdgeLengthInput_checkBox->setChecked(false);
228
229 }
Scene_edit_polyhedron_item(Scene_surface_mesh_item * sm_item,Ui::DeformMesh * ui_widget,QMainWindow * mw)230 Scene_edit_polyhedron_item::Scene_edit_polyhedron_item
231 (Scene_surface_mesh_item* sm_item,
232 Ui::DeformMesh* ui_widget,
233 QMainWindow* mw)
234 : Scene_group_item("unnamed")
235
236 {
237 mw->installEventFilter(this);
238 d = new Scene_edit_polyhedron_item_priv(sm_item, ui_widget, mw, this);
239 setTriangleContainer(Priv::Frame_plane, new Tc(Vi::PROGRAM_NO_SELECTION, true));
240 setTriangleContainer(Priv::Facets, new Tc(Vi::PROGRAM_WITH_LIGHT, true));
241 setEdgeContainer(Priv::Axis, new Ec(Vi::PROGRAM_NO_SELECTION, false));
242 setEdgeContainer(Priv::BBox, new Ec(Vi::PROGRAM_NO_SELECTION, false));
243 setEdgeContainer(Priv::Edges, new Ec(Vi::PROGRAM_NO_SELECTION, true));
244 setPointContainer(Priv::Control_points, new Pc(Vi::PROGRAM_NO_SELECTION, false));
245 setPointContainer(Priv::Roi_points, new Pc(Vi::PROGRAM_NO_SELECTION, false));
246 // bind vertex picking
247 connect(&d->k_ring_selector, SIGNAL(selected(const std::set<fg_vertex_descriptor>&)), this,
248 SLOT(selected(const std::set<fg_vertex_descriptor>&)));
249 id_setter = new Id_setter(d->sm_item->polyhedron());
250 d->deform_sm_mesh = new Deform_sm_mesh(*(sm_item->polyhedron()),
251 Deform_sm_mesh::Vertex_index_map(),
252 Deform_sm_mesh::Hedge_index_map(),
253 Array_based_vertex_point_map<SMesh>(&d->positions, surface_mesh(), id_setter));
254
255 d->length_of_axis = (CGAL::sqrt((bbox().xmax()-bbox().xmin())*(bbox().xmax()-bbox().xmin()) + (bbox().ymax()-bbox().ymin())*(bbox().ymax()-bbox().ymin()) + (bbox().zmax()-bbox().zmin())*(bbox().zmax()-bbox().zmin()))) / 15.0;
256 d->init_values();
257 connect(ui_widget->remeshingEdgeLengthInput_checkBox, SIGNAL(toggled(bool)),
258 ui_widget->remeshing_edge_length_spinbox, SLOT(setEnabled(bool)));
259 invalidateOpenGLBuffers();
260 }
261
~Scene_edit_polyhedron_item()262 Scene_edit_polyhedron_item::~Scene_edit_polyhedron_item()
263 {
264 while(is_there_any_ctrl_vertices_group())
265 {
266 d->delete_ctrl_vertices_group(surface_mesh(), false);
267 }
268
269 delete d;
270 delete id_setter;
271 }
272 /////////////////////////////
273 /// For the Shader gestion///
274
275 template<typename Mesh, typename M_Deform_mesh>
apply_reset_drawing_data(Mesh * mesh,M_Deform_mesh * m_deform_mesh)276 void Scene_edit_polyhedron_item_priv::apply_reset_drawing_data(Mesh* mesh, M_Deform_mesh* m_deform_mesh)
277 {
278
279 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
280 typedef typename boost::graph_traits<Mesh>::face_descriptor mesh_fd;
281 typedef typename boost::graph_traits<Mesh>::edge_iterator mesh_eit;
282 positions.resize(num_vertices(*mesh) * 3);
283 normals.resize(positions.size());
284 tris.resize(num_faces(*mesh) * 3);
285 _edges.resize(num_halfedges(*mesh));
286 std::size_t counter = 0;
287 typedef typename boost::property_map<Mesh, boost::vertex_point_t>::type VertexPointMap;
288 VertexPointMap vpmap = get(boost::vertex_point, *mesh);
289
290 for(mesh_vd vb : vertices(*mesh))
291 {
292 typename VertexPointMap::reference p = get(vpmap, vb);
293 positions[counter * 3] = p.x();
294 positions[counter * 3 + 1] = p.y();
295 positions[counter * 3 + 2] = p.z();
296 const EPICK::Vector_3& n =
297 CGAL::Polygon_mesh_processing::compute_vertex_normal(vb, m_deform_mesh->halfedge_graph());
298 normals[counter * 3] = n.x();
299 normals[counter * 3 + 1] = n.y();
300 normals[counter * 3 + 2] = n.z();
301
302 ++counter;
303 }
304 counter = 0;
305 Id_setter id_getter(mesh);
306
307 for(mesh_fd fb : faces(*mesh))
308 {
309 tris[counter * 3] = static_cast<unsigned int>(id_getter.get_id(target(halfedge(fb, *mesh), *mesh)));
310 tris[counter * 3 + 1] = static_cast<unsigned int>(id_getter.get_id(target(next(halfedge(fb, *mesh), *mesh), *mesh)));
311 tris[counter * 3 + 2] = static_cast<unsigned int>(id_getter.get_id(target(prev(halfedge(fb, *mesh), *mesh), *mesh)));
312 ++counter;
313 }
314
315 counter = 0;
316 for (mesh_eit it = edges(*mesh).first;
317 it != edges(*mesh).second; ++it, ++counter)
318 {
319 _edges[counter * 2] = static_cast<unsigned int>(id_getter.get_id(source(*it, *mesh)));
320 _edges[counter * 2 + 1] = static_cast<unsigned int>(id_getter.get_id(target(*it, *mesh)));
321 }
322 }
323
reset_drawing_data()324 void Scene_edit_polyhedron_item_priv::reset_drawing_data()
325 {
326 positions.clear();
327 normals.clear();
328 tris.clear();
329 _edges.clear();
330 if(sm_item)
331 apply_reset_drawing_data(sm_item->polyhedron(), deform_sm_mesh);
332 }
333
334 template<typename Mesh>
compute_normals_and_vertices(Mesh * mesh)335 void Scene_edit_polyhedron_item_priv::compute_normals_and_vertices(Mesh* mesh)
336 {
337 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
338
339 QApplication::setOverrideCursor(Qt::WaitCursor);
340 ROI_points.resize(0);
341 control_points.resize(0);
342 control_color.resize(0);
343 pos_frame_plane.resize(0);
344 const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset();
345 Facegraph_selector fs(this);
346 typedef typename boost::property_map<Mesh, boost::vertex_point_t>::type VertexPointMap;
347 VertexPointMap pmap = get(boost::vertex_point, *mesh);
348
349 for(mesh_vd vd : fs.get_deform_mesh(mesh)->roi_vertices())
350 {
351 if(!fs.get_deform_mesh(mesh)->is_control_vertex(vd))
352 {
353 EPICK::Point_3 p = get(pmap, vd);
354 ROI_points.push_back(p.x()+offset.x);
355 ROI_points.push_back(p.y()+offset.y);
356 ROI_points.push_back(p.z()+offset.z);
357
358 if(spheres)
359 {
360 CGAL::IO::Color c(0,255,0);
361 EPICK::Point_3 point(p.x()+offset.x, p.y()+offset.y, p.z()+offset.z);
362 spheres->add_sphere(EPICK::Sphere_3(point, length_of_axis/15.0*length_of_axis/15.0), 0, c);
363 }
364 }
365
366 }
367
368 for(typename std::list<Control_vertices_data<Mesh> >::const_iterator hgb_data = fs.get_ctrl_vertex_frame_map(mesh).begin(); hgb_data != fs.get_ctrl_vertex_frame_map(mesh).end(); ++hgb_data)
369 {
370 if(hgb_data->frame == Three::mainViewer()->manipulatedFrame())
371 {
372 if(!ui_widget->ActivatePivotingCheckBox->isChecked())
373 {
374 // draw bbox
375 compute_bbox(hgb_data->bbox);
376 }
377 }
378
379 const double r=hgb_data == fs.get_active_group(mesh)?1:0;
380 const double b=hgb_data == fs.get_active_group(mesh)?0:1;
381
382 for(typename std::vector<mesh_vd>::const_iterator hb = hgb_data->ctrl_vertices_group.begin(); hb != hgb_data->ctrl_vertices_group.end(); ++hb)
383 {
384 EPICK::Point_3 p = get(pmap, (*hb));
385 control_points.push_back(p.x()+offset.x);
386 control_points.push_back(p.y()+offset.y);
387 control_points.push_back(p.z()+offset.z);
388 control_color.push_back(r);
389 control_color.push_back(0);
390 control_color.push_back(b);
391
392 if(spheres_ctrl)
393 {
394 CGAL::IO::Color c(255*r,0,255*b);
395
396 EPICK::Point_3 center(p.x()+offset.x,
397 p.y()+offset.y,
398 p.z()+offset.z);
399 spheres_ctrl->add_sphere(EPICK::Sphere_3(center, length_of_axis/15.0*length_of_axis/15.0), 0, c);
400 }
401 }
402 }
403 //The axis
404
405 pos_axis.resize(18);
406 for(int i =0; i< 18; i++)
407 pos_axis[i]=0.0;
408 pos_axis[3] = length_of_axis; pos_axis[10] = length_of_axis; pos_axis[17] = length_of_axis;
409 color_lines.resize(18);
410 for(int i =0; i< 18; i++)
411 color_lines[i]=0.0;
412
413 color_lines[2] = 1.0; color_lines[5] = 1.0;
414 color_lines[6] = 1.0; color_lines[9] = 1.0;
415 color_lines[13] = 1.0; color_lines[16] = 1.0;
416
417 if(ui_widget->ActivateFixedPlaneCheckBox->isChecked())
418 {
419 item->draw_frame_plane(sm_item->polyhedron());
420 }
421 QApplication::restoreOverrideCursor();
422 }
423
424 /////////////////////////////////////////////////////////
425 /////////// Most relevant functions lie here ///////////
deform()426 void Scene_edit_polyhedron_item::deform()
427 {
428
429 if(!is_there_any_ctrl_vertices()) { return; }
430
431 d->deform(d->sm_item->polyhedron());
432 d->sm_item->invalidate_aabb_tree();
433 Q_EMIT itemChanged();
434 }
435
436 template<typename Mesh>
437 struct ROI_faces_pmap;
438
439 template<>
440 struct ROI_faces_pmap<SMesh>
441 {
442 typedef sm_face_descriptor key_type;
443 typedef std::size_t value_type;
444 typedef std::size_t& reference;
445 typedef boost::read_write_property_map_tag category;
446 SMesh* mesh;
447 SMesh::Property_map<sm_face_descriptor,bool> irmap;
ROI_faces_pmapROI_faces_pmap448 ROI_faces_pmap(std::map<key_type, value_type>*, SMesh* mesh)
449 :mesh(mesh)
450 {
451 //add a is_ROI property_map to mesh
452 irmap = mesh->add_property_map<sm_face_descriptor,bool>("f:is_roi",false).first;
453 }
454
get(const ROI_faces_pmap<SMesh> & pmap,const key_type & f)455 friend value_type get(const ROI_faces_pmap<SMesh>&pmap, const key_type& f)
456 {
457 if(get(pmap.irmap, f)) return 1;
458 else return 0;
459 }
put(ROI_faces_pmap<SMesh> & pmap,const key_type & f,const value_type b)460 friend void put(ROI_faces_pmap<SMesh>&pmap, const key_type& f, const value_type b)
461 {
462 if(b == 1)
463 put(pmap.irmap, f, true);
464 else
465 put(pmap.irmap, f, false);
466 }
467 };
468
469
470 template<typename Mesh>
471 struct ROI_border_pmap
472 {
473 typedef typename boost::graph_traits<Mesh>::edge_descriptor m_ed;
474 std::set<m_ed>* m_set_ptr;
475
476 typedef m_ed key_type;
477 typedef bool value_type;
478 typedef bool reference;
479 typedef boost::read_write_property_map_tag category;
480
ROI_border_pmapROI_border_pmap481 ROI_border_pmap() : m_set_ptr(NULL) {}
ROI_border_pmapROI_border_pmap482 ROI_border_pmap(std::set<m_ed>* set_)
483 : m_set_ptr(set_)
484 {}
get(const ROI_border_pmap<Mesh> & map,const key_type & k)485 friend bool get(const ROI_border_pmap<Mesh>& map, const key_type& k)
486 {
487 CGAL_assertion(map.m_set_ptr != nullptr);
488 return map.m_set_ptr->count(k);
489 }
put(ROI_border_pmap<Mesh> & map,const key_type & k,const value_type b)490 friend void put(ROI_border_pmap<Mesh>& map, const key_type& k, const value_type b)
491 {
492 CGAL_assertion(map.m_set_ptr != nullptr);
493 if (b) map.m_set_ptr->insert(k);
494 else if(get(map,k)) map.m_set_ptr->erase(k);
495 }
496 };
497
498 template<typename Mesh>
499 struct halfedge2edge
500 {
501 typedef typename boost::graph_traits<Mesh>::edge_descriptor m_ed;
502 typedef typename boost::graph_traits<Mesh>::halfedge_descriptor m_hd;
503
halfedge2edgehalfedge2edge504 halfedge2edge(const Mesh& m, std::set<m_ed>& edges)
505 : m_mesh(m), m_edges(edges)
506 {}
operator ()halfedge2edge507 void operator()(const m_hd& h) const
508 {
509 m_edges.insert(edge(h, m_mesh));
510 }
511 const Mesh& m_mesh;
512 std::set<m_ed>& m_edges;
513 };
514
remesh()515 void Scene_edit_polyhedron_item::remesh()
516 {
517 d->remesh(d->sm_item->polyhedron());
518 }
519
520 template<typename Mesh>
521 struct Is_constrained_map;
522
523 template<>
524 struct Is_constrained_map<SMesh>
525 {
526 typedef boost::graph_traits<SMesh>::vertex_descriptor mesh_vd;
527 typedef mesh_vd key_type;
528 typedef bool value_type;
529 typedef bool reference;
530 typedef boost::read_write_property_map_tag category;
531 SMesh::Property_map<sm_vertex_descriptor,int> icmap;
532 SMesh* mesh;
Is_constrained_mapIs_constrained_map533 Is_constrained_map()
534 {}
Is_constrained_mapIs_constrained_map535 Is_constrained_map(std::vector<int>* vec, SMesh* mesh)
536 :mesh(mesh)
537 {
538 icmap = mesh->add_property_map<sm_vertex_descriptor,int>("v:is_control", -1).first;
539 for(unsigned int i=0; i<vec->size(); ++i)
540 {
541 icmap[sm_vertex_descriptor(i)] = (*vec)[i];
542 }
543 }
544
cleanIs_constrained_map545 void clean(){ mesh->remove_property_map(icmap); }
546
get(const Is_constrained_map<SMesh> & map,const key_type & k)547 friend bool get(const Is_constrained_map<SMesh>& map, const key_type& k)
548 {
549 return map.icmap[k] != -1;
550 }
put(Is_constrained_map<SMesh> &,const key_type &,const value_type)551 friend void put(Is_constrained_map<SMesh>&, const key_type&, const value_type) //no need
552 {}
553 };
554
get_control_number(sm_vertex_descriptor v,const Is_constrained_map<SMesh> & map)555 int get_control_number(sm_vertex_descriptor v, const Is_constrained_map<SMesh>& map)
556 {
557 return get(map.icmap, v);
558 }
559
560 template<typename Mesh>
remesh(Mesh * mesh)561 void Scene_edit_polyhedron_item_priv::remesh(Mesh* mesh)
562 {
563 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
564 typedef typename boost::graph_traits<Mesh>::halfedge_descriptor mesh_hd;
565 typedef typename boost::graph_traits<Mesh>::face_descriptor mesh_fd;
566 typedef typename boost::graph_traits<Mesh>::edge_descriptor mesh_ed;
567 typedef typename CGAL::Surface_mesh_deformation<Mesh, CGAL::Default, CGAL::Default, CGAL::ORIGINAL_ARAP
568 ,CGAL::Default, CGAL::Default, CGAL::Default,
569 Array_based_vertex_point_map<Mesh> > M_Deform_mesh;
570
571
572 Facegraph_selector fs(this);
573 if(fs.get_deform_mesh(mesh)->roi_vertices().empty())
574 return;
575 std::vector<int> constrained_vec(num_vertices(*mesh), -1);
576 std::vector<std::vector<mesh_vd> > control_groups;
577 const Mesh& g = fs.get_deform_mesh(mesh)->halfedge_graph();
578
579 Array_based_vertex_point_map<Mesh> vpmap(&positions, mesh, item->id_setter);
580
581 std::set<mesh_fd> roi_facets;
582 std::set<mesh_vd> roi_vertices(
583 fs.get_deform_mesh(mesh)->roi_vertices().begin(),fs.get_deform_mesh(mesh)->roi_vertices().end());
584 QApplication::setOverrideCursor(Qt::WaitCursor);
585
586 //save the ROI list for after remeshing
587 //create control_groups and save their vertices in property_map
588 int id_group=0;
589 for(typename std::list<Control_vertices_data<Mesh> >::const_iterator hgb_data =
590 fs.get_ctrl_vertex_frame_map(mesh).begin();
591 hgb_data != fs.get_ctrl_vertex_frame_map(mesh).end(); ++hgb_data)
592 {
593 std::vector<mesh_vd> group;
594 for(mesh_vd vd : hgb_data->ctrl_vertices_group)
595 {
596 constrained_vec[item->id_setter->get_id(vd)] = id_group;
597 }
598 control_groups.push_back(group);
599 ++id_group;
600 }
601
602 std::map<mesh_fd, std::size_t> patch_map;
603 ROI_faces_pmap<Mesh> roi_faces_pmap(&patch_map, mesh);
604 //initialize face-patch_id map
605 for(mesh_vd v : fs.get_deform_mesh(mesh)->roi_vertices())
606 {
607 for(mesh_fd fv : CGAL::faces_around_target(halfedge(v, g), g))
608 {
609 if(fv == boost::graph_traits<Mesh>::null_face())
610 continue;
611 bool add_face=true;
612 for(mesh_vd vfd : CGAL::vertices_around_face(halfedge(fv,g),g))
613 if (roi_vertices.count(vfd)==0)
614 add_face=false;
615 if(add_face)
616 {
617 roi_facets.insert(fv);
618 put(roi_faces_pmap, fv, 1/*true*/);
619 }
620 }
621 }
622 if (roi_facets.empty())
623 {
624 std::cout << "Remeshing canceled (there is no facet with "
625 << "its 3 vertices in the ROI)." << std::endl;
626 QApplication::restoreOverrideCursor();
627 return;
628 }
629 // set face_index map needed for border_halfedges and isotropic_remeshing
630 unsigned int id = 0;
631
632 // estimate the target_length using the perimeter of the region to remesh
633 bool automatic_target_length = !ui_widget->remeshingEdgeLengthInput_checkBox->isChecked();
634 double estimated_target_length = 0.;
635 for(mesh_fd f : faces(*mesh))
636 item->id_setter->set_id(f, id++);
637
638 std::set<mesh_ed> roi_border;
639 CGAL::Polygon_mesh_processing::border_halfedges(roi_facets, g,
640 boost::make_function_output_iterator(halfedge2edge<Mesh>(g, roi_border)));
641
642 if (automatic_target_length)
643 {
644 double sum_len = 0.;
645 for(mesh_ed e : roi_border)
646 {
647 mesh_hd h = halfedge(e, g);
648 sum_len += CGAL::sqrt(CGAL::squared_distance(
649 get(vpmap, source(h, g)), get(vpmap, target(h, g))));
650 }
651 if (sum_len==0) automatic_target_length = false;
652 else
653 estimated_target_length = sum_len / (0. + roi_border.size());
654 }
655
656 double target_length = automatic_target_length
657 ? estimated_target_length
658 : ui_widget->remeshing_edge_length_spinbox->value();
659
660 unsigned int nb_iter = ui_widget->remeshing_iterations_spinbox->value();
661
662 std::cout << "Remeshing (target edge length = " << target_length <<")...";
663 Is_constrained_map<Mesh> icm(&constrained_vec, mesh);
664 ROI_border_pmap<Mesh> border_pmap(&roi_border);
665 CGAL::Polygon_mesh_processing::isotropic_remeshing(
666 roi_facets
667 , target_length
668 , *mesh
669 , CGAL::Polygon_mesh_processing::parameters::number_of_iterations(nb_iter)
670 .protect_constraints(false)
671 .vertex_point_map(vpmap)
672 .edge_is_constrained_map(border_pmap)
673 .face_patch_map(roi_faces_pmap)
674 .vertex_is_constrained_map(icm)
675 );
676 std::cout << "done." << std::endl;
677 fs.update_ids(mesh, true);
678 //reset ROI from its outside border roi_border
679 item->clear_roi();
680 do{
681 delete_ctrl_vertices_group(sm_item->polyhedron(), false);
682 }
683 while(!fs.get_ctrl_vertex_frame_map(mesh).empty());
684
685 fs.update_ids(mesh, false);
686 delete fs.get_deform_mesh(mesh);
687 fs.set_deform_mesh(mesh, new M_Deform_mesh(*(mesh),
688 typename M_Deform_mesh::Vertex_index_map(),
689 typename M_Deform_mesh::Hedge_index_map(),
690 vpmap));
691
692 //fill control_groups
693 id_group = -1;
694 for(mesh_vd v : vertices(*mesh) )
695 {
696 id_group = get_control_number(v, icm);
697 if(id_group == -1)
698 continue;
699 control_groups[id_group].push_back(v);
700 }
701 icm.clean();
702 //re-create ctrl_groups
703 for(std::size_t i=0; i<control_groups.size() ; i++)
704 {
705 item->create_ctrl_vertices_group();
706 for(mesh_vd vd : control_groups[i]){
707 item->insert_control_vertex<Mesh>(vd, mesh);
708 }
709 }
710
711 for(mesh_fd f : faces(g))
712 {
713 if (get(roi_faces_pmap, f) == 0/*false*/)
714 continue;
715 for(mesh_hd h : halfedges_around_face(halfedge(f, g), g))
716 {
717 mesh_vd v = target(h, g);
718 item->insert_roi_vertex<Mesh>(v, mesh);
719 }
720 put(roi_faces_pmap, f, 0/*false*/); //reset ids
721 }
722
723 reset_drawing_data();
724 item->computeElements();
725 fs.invalidate_aabb_tree(mesh); // invalidate the AABB tree
726 QApplication::restoreOverrideCursor();
727 Q_EMIT item->itemChanged();
728 }
729
730 template<typename Mesh>
deform(Mesh * mesh)731 void Scene_edit_polyhedron_item_priv::deform(Mesh* mesh)
732 {
733 Facegraph_selector fs(this);
734 for(typename std::list<Control_vertices_data<Mesh> >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin();
735 it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it)
736 { it->set_target_positions(); }
737 fs.get_deform_mesh(mesh)->deform();
738 }
739
updateDeform()740 void Scene_edit_polyhedron_item::updateDeform()
741 {
742 if(d->need_change)
743 {
744 // just handle deformation - paint like selection is handled in eventFilter()
745 invalidateOpenGLBuffers();
746 if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()) {
747 deform();
748 }
749 else {
750 Q_EMIT itemChanged(); // for redraw while Pivoting (since we close signals of manipulatedFrames while pivoting,
751 // for now redraw with timer)
752 }
753 d->need_change = 0;
754 }
755 }
756
change()757 void Scene_edit_polyhedron_item::change()
758 {
759 d->need_change = true;
760 QTimer::singleShot(0, this, SLOT(updateDeform()));
761 }
762
763 template<typename Mesh>
764 struct Is_selected_property_map{
765 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
766
767 Mesh* mesh;
768 std::vector<bool>* is_selected_ptr;
Is_selected_property_mapIs_selected_property_map769 Is_selected_property_map()
770 : mesh(NULL), is_selected_ptr(nullptr) {}
Is_selected_property_mapIs_selected_property_map771 Is_selected_property_map(std::vector<bool>& is_selected, Mesh* mesh)
772 : mesh(mesh), is_selected_ptr( &is_selected) {}
773
idIs_selected_property_map774 std::size_t id(mesh_vd v)
775 {
776 Id_setter is(mesh);
777 return is.get_id(v);
778 }
779
get(Is_selected_property_map<Mesh> map,mesh_vd v)780 friend bool get(Is_selected_property_map<Mesh> map, mesh_vd v)
781 {
782 CGAL_assertion(map.is_selected_ptr!=nullptr);
783 return (*map.is_selected_ptr)[map.id(v)];
784 }
785
put(Is_selected_property_map<Mesh> map,mesh_vd v,bool b)786 friend void put(Is_selected_property_map<Mesh> map, mesh_vd v, bool b)
787 {
788 CGAL_assertion(map.is_selected_ptr!=nullptr);
789 (*map.is_selected_ptr)[map.id(v)]=b;
790 }
791 };
792 template<typename Mesh>
expand_or_reduce(int steps,Mesh * mesh)793 void Scene_edit_polyhedron_item_priv::expand_or_reduce(int steps, Mesh* mesh)
794 {
795
796 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
797 Facegraph_selector fs(this);
798 Id_setter id_getter(mesh);
799 std::vector<bool> mark(num_vertices(*mesh),false);
800
801 bool ctrl_active = ui_widget->CtrlVertRadioButton->isChecked();
802 if (ctrl_active && fs.get_active_group(mesh) == fs.get_ctrl_vertex_frame_map(mesh).end() ) return;
803 std::size_t original_size;
804 if(ctrl_active)
805 original_size = fs.get_active_group(mesh)->ctrl_vertices_group.size();
806 else
807 original_size = fs.get_deform_mesh(mesh)->roi_vertices().size();
808 for(mesh_vd v :fs.get_deform_mesh(mesh)->roi_vertices())
809 {
810 if(ctrl_active)
811 {
812 if(fs.get_deform_mesh(mesh)->is_control_vertex(v))
813 mark[id_getter.get_id(v)]=true;
814 }
815 else
816 {
817 if(!fs.get_deform_mesh(mesh)->is_control_vertex(v))
818 mark[id_getter.get_id(v)]=true;
819 }
820 }
821 std::vector<bool> mask = mark;
822 if(steps > 0)
823 {
824 if(ctrl_active)
825 expand_vertex_selection(fs.get_active_group(mesh)->ctrl_vertices_group, *mesh, steps, Is_selected_property_map<Mesh>(mark, mesh),
826 CGAL::Emptyset_iterator());
827 else
828 expand_vertex_selection(fs.get_deform_mesh(mesh)->roi_vertices(), *mesh, steps, Is_selected_property_map<Mesh>(mark, mesh),
829 CGAL::Emptyset_iterator());
830 }
831 else
832 {
833 if(ctrl_active)
834 reduce_vertex_selection(fs.get_active_group(mesh)->ctrl_vertices_group, *mesh, -steps, Is_selected_property_map<Mesh>(mark, mesh),
835 CGAL::Emptyset_iterator());
836 else
837 reduce_vertex_selection(fs.get_deform_mesh(mesh)->roi_vertices(), *mesh, -steps, Is_selected_property_map<Mesh>(mark, mesh),
838 CGAL::Emptyset_iterator());
839 }
840
841 for(typename boost::graph_traits<Mesh>::vertex_iterator it = vertices(*mesh).begin() ; it != vertices(*mesh).end(); ++it)
842 {
843 if(ctrl_active)
844 {
845 if(mark[id_getter.get_id(*it)] && !mask[id_getter.get_id(*it)])
846 item->insert_control_vertex<Mesh>(*it, mesh);
847 else if(!mark[id_getter.get_id(*it)] && mask[id_getter.get_id(*it)])
848 item->erase_control_vertex<Mesh>(*it, mesh);
849 }
850 else
851 {
852 if(mark[id_getter.get_id(*it)] && !mask[id_getter.get_id(*it)])
853 item->insert_roi_vertex<Mesh>(*it, mesh);
854 else if(!mark[id_getter.get_id(*it)] && mask[id_getter.get_id(*it)])
855 item->erase_roi_vertex<Mesh>(*it, mesh);
856 }
857 }
858 if(fs.get_active_group(mesh)->ctrl_vertices_group.empty() && fs.get_ctrl_vertex_frame_map(mesh).size()>1)
859 {
860 delete_ctrl_vertices_group(sm_item->polyhedron(), false);
861 }
862 if(
863 (!ctrl_active && fs.get_deform_mesh(mesh)->roi_vertices().size() != original_size)
864 || (ctrl_active && fs.get_active_group(mesh)->ctrl_vertices_group.size() != original_size)
865 )
866 { item->invalidateOpenGLBuffers(); Q_EMIT item->itemChanged(); }
867 }
868
eventFilter(QObject *,QEvent * event)869 bool Scene_edit_polyhedron_item::eventFilter(QObject* /*target*/, QEvent *event)
870 {
871 // This filter is both filtering events from 'viewer' and 'main window'
872 Mouse_keyboard_state_deformation old_state = d->state;
873 ////////////////// TAKE EVENTS /////////////////////
874 // key events
875 if(event->type() == QEvent::KeyPress || event->type() == QEvent::KeyRelease)
876 {
877 QKeyEvent *keyEvent = static_cast<QKeyEvent*>(event);
878 Qt::KeyboardModifiers modifiers = keyEvent->modifiers();
879
880 d->state.ctrl_pressing = modifiers.testFlag(Qt::ControlModifier);
881 d->state.shift_pressing = modifiers.testFlag(Qt::ShiftModifier);
882 }
883 // mouse events
884 if(event->type() == QEvent::Wheel
885 &&d->state.shift_pressing)
886 {
887 QWheelEvent *w_event = static_cast<QWheelEvent*>(event);
888 int steps = w_event->angleDelta().y() / 120;
889 d->expand_or_reduce(steps, d->sm_item->polyhedron());
890 }
891 if(event->type() == QEvent::MouseButtonPress || event->type() == QEvent::MouseButtonRelease)
892 {
893 QMouseEvent* mouse_event = static_cast<QMouseEvent*>(event);
894 if(mouse_event->button() == Qt::LeftButton) {
895 d->state.left_button_pressing = event->type() == QEvent::MouseButtonPress;
896 }
897 if(mouse_event->button() == Qt::RightButton) {
898 d->state.right_button_pressing = event->type() == QEvent::MouseButtonPress;
899 }
900 }
901 ////////////////// //////////////// /////////////////////
902
903 if((d->sm_item && !d->sm_item->visible())){ return false; } // if not visible just update event state but don't do any action
904
905 // check state changes between old and current state
906 bool ctrl_pressed_now = d->state.ctrl_pressing && !old_state.ctrl_pressing;
907 bool ctrl_released_now = !d->state.ctrl_pressing && old_state.ctrl_pressing;
908 if(ctrl_released_now) //to avoid moving the control vertices next time ctrl is pressed
909 d->state.left_button_pressing = false;
910 if(ctrl_pressed_now || ctrl_released_now || event->type() == QEvent::HoverMove)
911 {// activate a handle manipulated frame
912 CGAL::QGLViewer* viewer = Three::mainViewer();
913 const QPoint& p = viewer->mapFromGlobal(QCursor::pos());
914
915 bool need_repaint;
916 need_repaint = activate_closest_manipulated_frame<SMesh>(p.x(), p.y(), surface_mesh());
917
918 if (!d->ui_widget->ActivatePivotingCheckBox->isChecked() &&
919 ctrl_released_now && d->ui_widget->RemeshingCheckBox->isChecked())
920 {
921 remesh();
922 }
923 if(need_repaint)
924 invalidateOpenGLBuffers();
925
926 need_repaint |= d->state.left_button_pressing || d->state.right_button_pressing;
927 if(need_repaint) { Q_EMIT itemChanged(); }
928 }
929
930 return false;
931 }
932
933
drawEdges(CGAL::Three::Viewer_interface * viewer) const934 void Scene_edit_polyhedron_item::drawEdges(CGAL::Three::Viewer_interface* viewer) const {
935 init(viewer);
936 Ec* ec = getEdgeContainer(Priv::Edges);
937 ec->setColor(QColor(0,0,0));
938 ec->draw(viewer, true);
939 }
draw(CGAL::Three::Viewer_interface * viewer) const940 void Scene_edit_polyhedron_item::draw(CGAL::Three::Viewer_interface* viewer) const {
941 init(viewer);
942 Tc* tc = getTriangleContainer(Priv::Facets);
943 tc->setColor(this->color());
944 tc->draw(viewer, true);
945 //drawEdges(viewer);
946 draw_ROI_and_control_vertices(viewer);
947 drawTransparent(viewer);
948 }
949
drawTransparent(Viewer_interface * viewer) const950 void Scene_edit_polyhedron_item::drawTransparent(Viewer_interface *viewer) const
951 {
952 if(d->ui_widget->ActivateFixedPlaneCheckBox->isChecked())
953 {
954 viewer->glEnable(GL_BLEND);
955 viewer->glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
956 Tc* tc = getTriangleContainer(Priv::Frame_plane);
957 tc->setColor(QColor(128,64,64,128));
958 tc->setAlpha(0.5);
959 tc->draw(viewer, true);
960 viewer->glDisable(GL_BLEND);
961 }
962 }
963
964 template<typename Mesh>
draw_frame_plane(Mesh * mesh) const965 void Scene_edit_polyhedron_item::draw_frame_plane(Mesh* mesh) const
966 {
967 d->pos_frame_plane.resize(12);
968 Facegraph_selector fs;
969 for(typename std::list<Control_vertices_data<Mesh> >::const_iterator hgb_data = fs.get_ctrl_vertex_frame_map(mesh, d).begin();
970 hgb_data != fs.get_ctrl_vertex_frame_map(mesh, d).end(); ++hgb_data)
971 {
972 const double diag = scene_diag();
973 CGAL::qglviewer::Vec base1(1,0,0);
974 CGAL::qglviewer::Vec base2(0,1,0);
975
976 CGAL::qglviewer::Quaternion orientation=hgb_data->frame->orientation();
977 base1=orientation.rotate(base1);
978 base2=orientation.rotate(base2);
979
980 CGAL::qglviewer::Vec center = hgb_data->calculate_initial_center();
981 CGAL::qglviewer::Vec p1 = center - diag*base1 - diag*base2;
982 CGAL::qglviewer::Vec p2 = center + diag*base1 - diag*base2;
983 CGAL::qglviewer::Vec p3 = center + diag*base1 + diag*base2;
984 CGAL::qglviewer::Vec p4 = center - diag*base1 + diag*base2;
985
986 d->pos_frame_plane[0] = p1.x ; d->pos_frame_plane[1] = p1.y; d->pos_frame_plane[2] =p1.z ;
987 d->pos_frame_plane[3] = p2.x ; d->pos_frame_plane[4] = p2.y; d->pos_frame_plane[5] =p2.z ;
988 d->pos_frame_plane[6] = p3.x ; d->pos_frame_plane[7] = p3.y; d->pos_frame_plane[8] =p3.z ;
989 d->pos_frame_plane[9] = p4.x ; d->pos_frame_plane[10]= p4.y; d->pos_frame_plane[11] =p4.z ;
990 d->plane_idx.push_back(0);
991 d->plane_idx.push_back(1);
992 d->plane_idx.push_back(2);
993 d->plane_idx.push_back(0);
994 d->plane_idx.push_back(2);
995 d->plane_idx.push_back(3);
996
997 }
998 }
draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface * viewer,CGAL::qglviewer::ManipulatedFrame * frame,const CGAL::qglviewer::Vec & center) const999 void Scene_edit_polyhedron_item_priv::draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer, CGAL::qglviewer::ManipulatedFrame* frame, const CGAL::qglviewer::Vec ¢er) const
1000 {
1001 // Draw the axis
1002
1003 if(frame == Three::mainViewer()->manipulatedFrame())
1004 {
1005 GLfloat f_matrix[16];
1006 for(int i =0; i<16; i++)
1007 f_matrix[i] = frame->matrix()[i];
1008 QMatrix4x4 f_mat;
1009 for(int i=0; i<16; i++)
1010 f_mat.data()[i] = (float)f_matrix[i];
1011 Ec* ec = item->getEdgeContainer(Priv::Axis);
1012 ec->setFrameMatrix(f_mat);
1013 ec->draw(viewer, false);
1014
1015 // draw bbox
1016 if(!ui_widget->ActivatePivotingCheckBox->isChecked())
1017 {
1018 GLfloat f_matrix[16];
1019 GLfloat vtrans[3];
1020 GLfloat vtrans2[3];
1021
1022 vtrans[0] = frame->position().x;
1023 vtrans[1] = frame->position().y;
1024 vtrans[2] = frame->position().z;
1025
1026 vtrans2[0] = -center.x;
1027 vtrans2[1] = -center.y;
1028 vtrans2[2] = -center.z;
1029
1030 for(int i =0; i<16; i++)
1031 f_matrix[i] = frame->orientation().matrix()[i];
1032 QMatrix4x4 f_mat, temp_mat;
1033 QMatrix4x4 trans; trans.translate(vtrans[0], vtrans[1], vtrans[2]);
1034 QMatrix4x4 trans2; trans2.translate(vtrans2[0], vtrans2[1], vtrans2[2]);
1035 for(int i=0; i<16; i++)
1036 temp_mat.data()[i] = (float)f_matrix[i];
1037 f_mat = trans*temp_mat*trans2;
1038 ec = item->getEdgeContainer(Priv::BBox);
1039 ec->setFrameMatrix(f_mat);
1040 ec->setColor(QColor(255,0,0));
1041 ec->draw(viewer, true);
1042 }
1043 }
1044 }
draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface * viewer) const1045 void Scene_edit_polyhedron_item::draw_ROI_and_control_vertices(CGAL::Three::Viewer_interface* viewer) const {
1046 viewer->setGlPointSize(5);
1047 //Draw the points
1048 if(d->ui_widget->ShowROICheckBox->isChecked()) {
1049
1050 if(!d->ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->isExtensionFound()) {
1051
1052 Pc* pc = getPointContainer(Priv::Roi_points);
1053 pc->setColor(QColor(0,255,0));
1054 pc->draw(viewer, true);
1055 }
1056 else
1057 {
1058 d->spheres->setVisible(true);
1059 Scene_group_item::draw(viewer);
1060 }
1061 }
1062 else
1063 {
1064 if(d->ui_widget->ShowAsSphereCheckBox->isChecked() && viewer->isExtensionFound()) {
1065 d->spheres->setVisible(false);
1066 Scene_group_item::draw(viewer);
1067 }
1068 }
1069
1070 if(!d->ui_widget->ShowAsSphereCheckBox->isChecked() || !viewer->isExtensionFound()) {
1071 Pc* pc = getPointContainer(Priv::Control_points);
1072 pc->draw(viewer, false);
1073 }
1074 for(Ctrl_vertices_sm_group_data_list::const_iterator hgb_data = d->sm_ctrl_vertex_frame_map.begin();
1075 hgb_data != d->sm_ctrl_vertex_frame_map.end(); ++hgb_data)
1076 {
1077 d->draw_ROI_and_control_vertices(viewer, hgb_data->frame, hgb_data->frame_initial_center);
1078 }
1079
1080 viewer->setGlPointSize(1);
1081 }
1082
1083
compute_bbox(const CGAL::Three::Scene_interface::Bbox & bb)1084 void Scene_edit_polyhedron_item_priv::compute_bbox(const CGAL::Three::Scene_interface::Bbox& bb){
1085 pos_bbox.resize(24*3);
1086
1087 pos_bbox[0]=bb.xmin(); pos_bbox[1]=bb.ymin(); pos_bbox[2]=bb.zmin();
1088 pos_bbox[3]=bb.xmax(); pos_bbox[4]=bb.ymin(); pos_bbox[5]=bb.zmin();
1089 pos_bbox[6]=bb.xmin(); pos_bbox[7]=bb.ymin(); pos_bbox[8]=bb.zmin();
1090 pos_bbox[9]=bb.xmin(); pos_bbox[10]=bb.ymax(); pos_bbox[11]=bb.zmin();
1091
1092 pos_bbox[12]=bb.xmin(); pos_bbox[13]=bb.ymin(); pos_bbox[14]=bb.zmin();
1093 pos_bbox[15]=bb.xmin(); pos_bbox[16]=bb.ymin(); pos_bbox[17]=bb.zmax();
1094 pos_bbox[18]= bb.xmax(); pos_bbox[19]=bb.ymin(); pos_bbox[20]=bb.zmin();
1095 pos_bbox[21]= bb.xmax(); pos_bbox[22]=bb.ymax(); pos_bbox[23]=bb.zmin();
1096
1097 pos_bbox[24]= bb.xmax(); pos_bbox[25]=bb.ymin(); pos_bbox[26]=bb.zmin();
1098 pos_bbox[27]= bb.xmax(); pos_bbox[28]=bb.ymin(); pos_bbox[29]=bb.zmax();
1099 pos_bbox[30]=bb.xmin(); pos_bbox[31]=bb.ymax(); pos_bbox[32]=bb.zmin();
1100 pos_bbox[33]=bb.xmax(); pos_bbox[34]=bb.ymax(); pos_bbox[35]=bb.zmin();
1101
1102 pos_bbox[36]=bb.xmin(); pos_bbox[37]=bb.ymax(); pos_bbox[38]=bb.zmin();
1103 pos_bbox[39]=bb.xmin(); pos_bbox[40]=bb.ymax(); pos_bbox[41]=bb.zmax();
1104 pos_bbox[42]=bb.xmin(); pos_bbox[43]=bb.ymin(); pos_bbox[44]=bb.zmax();
1105 pos_bbox[45]=bb.xmax(); pos_bbox[46]=bb.ymin(); pos_bbox[47]=bb.zmax();
1106
1107 pos_bbox[48]=bb.xmin(); pos_bbox[49]=bb.ymin(); pos_bbox[50]=bb.zmax();
1108 pos_bbox[51]=bb.xmin(); pos_bbox[52]=bb.ymax(); pos_bbox[53]=bb.zmax();
1109 pos_bbox[54]=bb.xmax(); pos_bbox[55]=bb.ymax(); pos_bbox[56]=bb.zmax();
1110 pos_bbox[57]=bb.xmin(); pos_bbox[58]=bb.ymax(); pos_bbox[59]=bb.zmax();
1111
1112 pos_bbox[60]=bb.xmax(); pos_bbox[61]=bb.ymax(); pos_bbox[62]=bb.zmax();
1113 pos_bbox[63]=bb.xmax(); pos_bbox[64]=bb.ymin(); pos_bbox[65]=bb.zmax();
1114 pos_bbox[66]=bb.xmax(); pos_bbox[67]=bb.ymax(); pos_bbox[68]=bb.zmax();
1115 pos_bbox[69]=bb.xmax(); pos_bbox[70]=bb.ymax(); pos_bbox[71]=bb.zmin();
1116
1117 }
1118
invalidateOpenGLBuffers()1119 void Scene_edit_polyhedron_item::invalidateOpenGLBuffers()
1120 {
1121 if(d->spheres)
1122 d->spheres->clear_spheres();
1123 if(d->spheres_ctrl)
1124 d->spheres_ctrl->clear_spheres();
1125 update_normals();
1126 compute_bbox();
1127 for(int i=0; i< 2; ++i)
1128 {
1129 getTriangleContainer(i)->reset_vbos(ALL);
1130 getPointContainer(i)->reset_vbos(ALL);
1131 getEdgeContainer(i)->reset_vbos(ALL);
1132 }
1133 getEdgeContainer(2)->reset_vbos(ALL);
1134 setBuffersFilled(false);
1135 Q_FOREACH(CGAL::QGLViewer* v, CGAL::QGLViewer::QGLViewerPool())
1136 {
1137 CGAL::Three::Viewer_interface* viewer = static_cast<CGAL::Three::Viewer_interface*>(v);
1138 if(viewer == nullptr)
1139 continue;
1140 setBuffersInit(viewer, false);
1141 viewer->update();
1142 }
1143 if(d->spheres)
1144 d->spheres->invalidateOpenGLBuffers();
1145 if(d->spheres_ctrl)
1146 d->spheres_ctrl->invalidateOpenGLBuffers();
1147 }
1148
to_sm_item()1149 Scene_surface_mesh_item* Scene_edit_polyhedron_item::to_sm_item() {
1150 Scene_surface_mesh_item* sm_item_tmp = d->sm_item;
1151 d->own_poly_item=false;
1152 sm_item_tmp->invalidateOpenGLBuffers();
1153 return sm_item_tmp;
1154 }
1155
surface_mesh()1156 SMesh* Scene_edit_polyhedron_item::surface_mesh()
1157 { return d->sm_item->polyhedron(); }
surface_mesh() const1158 const SMesh* Scene_edit_polyhedron_item::surface_mesh() const
1159 { return d->sm_item->polyhedron(); }
1160
1161
toolTip() const1162 QString Scene_edit_polyhedron_item::toolTip() const
1163 {
1164 if(!d->sm_item->polyhedron())
1165 return QString();
1166
1167 return QObject::tr("<p>Surface Mesh <b>%1</b> (mode: %5, color: %6)</p>"
1168 "<p>Number of vertices: %2<br />"
1169 "Number of edges: %3<br />"
1170 "Number of facets: %4</p>")
1171 .arg(this->name())
1172 .arg(num_vertices(*d->sm_item->polyhedron()))
1173 .arg(num_halfedges(*d->sm_item->polyhedron())/2)
1174 .arg(num_faces(*d->sm_item->polyhedron()))
1175 .arg(this->renderingModeName())
1176 .arg(this->color().name());
1177 }
1178
isEmpty() const1179 bool Scene_edit_polyhedron_item::isEmpty() const {
1180 return d->sm_item->isEmpty();
1181 }
compute_bbox() const1182 void Scene_edit_polyhedron_item::compute_bbox() const {
1183 setBbox(d->sm_item->bbox());
1184 }
1185
setVisible(bool b)1186 void Scene_edit_polyhedron_item::setVisible(bool b) {
1187 d->sm_item->setVisible(b);
1188 Scene_item::setVisible(b);
1189 if(!b) {
1190 Three::mainViewer()->setManipulatedFrame(nullptr);
1191 }
1192 }
setColor(QColor c)1193 void Scene_edit_polyhedron_item::setColor(QColor c) {
1194 d->sm_item->setColor(c);
1195 Scene_item::setColor(c);
1196 }
setName(QString n)1197 void Scene_edit_polyhedron_item::setName(QString n) {
1198 Scene_item::setName(n);
1199 n.replace(" (edit)", "");
1200 d->sm_item->setName(n);
1201 }
setRenderingMode(RenderingMode m)1202 void Scene_edit_polyhedron_item::setRenderingMode(RenderingMode m) {
1203 d->sm_item->setRenderingMode(m);
1204 Scene_item::setRenderingMode(m);
1205 }
clone() const1206 Scene_edit_polyhedron_item* Scene_edit_polyhedron_item::clone() const {
1207 return nullptr;
1208 }
select(double orig_x,double orig_y,double orig_z,double dir_x,double dir_y,double dir_z)1209 void Scene_edit_polyhedron_item::select(
1210 double orig_x,
1211 double orig_y,
1212 double orig_z,
1213 double dir_x,
1214 double dir_y,
1215 double dir_z)
1216 {
1217 Scene_item::select(orig_x,
1218 orig_y,
1219 orig_z,
1220 dir_x,
1221 dir_y,
1222 dir_z);
1223 d->sm_item->select(orig_x,
1224 orig_y,
1225 orig_z,
1226 dir_x,
1227 dir_y,
1228 dir_z);
1229
1230 }
1231
keyPressEvent(QKeyEvent * e)1232 bool Scene_edit_polyhedron_item::keyPressEvent(QKeyEvent* e)
1233 {
1234 //setting/unsetting rotation constraints
1235 if (e->key()==Qt::Key_R && !d->state.ctrl_pressing)
1236 {
1237 d->is_rot_free = !d->is_rot_free;
1238 d->rot_constraint.setRotationConstraintType( d->is_rot_free?
1239 CGAL::qglviewer::AxisPlaneConstraint::FREE:
1240 CGAL::qglviewer::AxisPlaneConstraint::AXIS);
1241 return true;
1242 }
1243
1244 return false;
1245 }
1246
1247
update_frame_plane()1248 void Scene_edit_polyhedron_item::update_frame_plane()
1249 {
1250
1251 for(Ctrl_vertices_sm_group_data_list::iterator hgb_data = d->sm_ctrl_vertex_frame_map.begin();
1252 hgb_data != d->sm_ctrl_vertex_frame_map.end(); ++hgb_data)
1253 {
1254 hgb_data->refresh(surface_mesh());
1255 }
1256 }
1257
1258
1259 struct Reset_spheres_ctrl
1260 {
1261 Scene_edit_polyhedron_item_priv* d;
Reset_spheres_ctrlReset_spheres_ctrl1262 Reset_spheres_ctrl(Scene_edit_polyhedron_item_priv* d) : d(d) {}
operator ()Reset_spheres_ctrl1263 void operator()() const { d->spheres_ctrl = nullptr; }
1264 };
1265
ShowAsSphere(bool b)1266 void Scene_edit_polyhedron_item::ShowAsSphere(bool b)
1267 {
1268 if(b)
1269 {
1270 if(!d->spheres)
1271 {
1272 d->spheres = new Scene_spheres_item(this, 0, false, false);
1273 d->spheres->setName("ROI spheres");
1274 d->spheres->setRenderingMode(Gouraud);
1275 connect(d->spheres, SIGNAL(destroyed()), this, SLOT(reset_spheres()));
1276 scene->setSelectedItem(scene->item_id(this));
1277 scene->addItem(d->spheres);
1278 scene->changeGroup(d->spheres, this);
1279 lockChild(d->spheres);
1280 invalidateOpenGLBuffers();
1281 }
1282 if(!d->spheres_ctrl)
1283 {
1284 d->spheres_ctrl = new Scene_spheres_item(this, false, false);
1285 d->spheres_ctrl->setName("Control spheres");
1286 d->spheres_ctrl->setRenderingMode(Gouraud);
1287 connect(d->spheres_ctrl, &QObject::destroyed, this, Reset_spheres_ctrl(d) );
1288 scene->setSelectedItem(scene->item_id(this));
1289 scene->addItem(d->spheres_ctrl);
1290 scene->changeGroup(d->spheres_ctrl, this);
1291 lockChild(d->spheres_ctrl);
1292 invalidateOpenGLBuffers();
1293 }
1294 }
1295 else if(!b )
1296 {
1297 if(d->spheres!=nullptr)
1298 {
1299 unlockChild(d->spheres);
1300 removeChild(d->spheres);
1301 scene->erase(scene->item_id(d->spheres));
1302 }
1303 if(d->spheres_ctrl!=nullptr)
1304 {
1305 unlockChild(d->spheres_ctrl);
1306 removeChild(d->spheres_ctrl);
1307 scene->erase(scene->item_id(d->spheres_ctrl));
1308 }
1309 }
1310 }
1311
is_there_any_ctrl_vertices_group(Ctrl_vertices_sm_group_data_list::iterator & hgb,Ctrl_vertices_sm_group_data_list::iterator & hge)1312 bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices_group(Ctrl_vertices_sm_group_data_list::iterator& hgb,
1313 Ctrl_vertices_sm_group_data_list::iterator& hge)
1314 {
1315 hgb = d->sm_ctrl_vertex_frame_map.begin(); hge = d->sm_ctrl_vertex_frame_map.end();
1316 return hgb != hge;
1317 }
get_k_ring()1318 int Scene_edit_polyhedron_item::get_k_ring() { return d->k_ring_selector.k_ring; }
set_k_ring(int v)1319 void Scene_edit_polyhedron_item::set_k_ring(int v) { d->k_ring_selector.k_ring = v; }
1320
reset_spheres()1321 void Scene_edit_polyhedron_item::reset_spheres()
1322 {
1323 d->spheres = nullptr;
1324 }
1325
1326
selected(const std::set<fg_vertex_descriptor> & m)1327 void Scene_edit_polyhedron_item::selected(const std::set<fg_vertex_descriptor>& m)
1328 {
1329 bool any_changes = false;
1330 for(std::set<fg_vertex_descriptor>::const_iterator it = m.begin(); it != m.end(); ++it)
1331 {
1332 sm_vertex_descriptor vh = *it;
1333 bool changed = false;
1334 if(d->ui_widget->ROIRadioButton->isChecked()) {
1335 if(d->ui_widget->InsertRadioButton->isChecked()) { changed = insert_roi_vertex<SMesh>(vh, surface_mesh());}
1336 else { changed = erase_roi_vertex<SMesh>(vh, surface_mesh()); }
1337 }
1338 else {
1339 if(d->ui_widget->InsertRadioButton->isChecked()) { changed = insert_control_vertex<SMesh>(vh, surface_mesh()); }
1340 else { changed = erase_control_vertex<SMesh>(vh, surface_mesh()); }
1341 }
1342 any_changes |= changed;
1343 }
1344 if(any_changes) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); }
1345 }
1346
1347 template<typename Mesh>
insert_control_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v,Mesh * mesh)1348 bool Scene_edit_polyhedron_item::insert_control_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v, Mesh* mesh)
1349 {
1350 if(!is_there_any_ctrl_vertices_group()) {
1351 std::cerr<<"There is no group of control vertices, create one!\n";
1352 return false;
1353 } // no group of control vertices to insert
1354
1355 Facegraph_selector fs(d);
1356 bool inserted = fs.get_deform_mesh(mesh)->insert_control_vertex(v);
1357 if(inserted) {
1358 fs.get_active_group(mesh)->ctrl_vertices_group.push_back(v);
1359 fs.get_active_group(mesh)->refresh(mesh);
1360 }
1361 return inserted;
1362 }
1363 template<typename Mesh>
insert_roi_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v,Mesh * mesh)1364 bool Scene_edit_polyhedron_item::insert_roi_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v, Mesh* mesh)
1365 {
1366 Facegraph_selector fs(d);
1367 return fs.get_deform_mesh(mesh)->insert_roi_vertex(v);
1368 }
1369 template<typename Mesh>
erase_control_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v,Mesh * mesh)1370 bool Scene_edit_polyhedron_item::erase_control_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v, Mesh* mesh)
1371 {
1372 Facegraph_selector fs(d);
1373 if(fs.get_deform_mesh(mesh)->erase_control_vertex(v)) // API should be safe enough to do that (without checking empty group of control vertices etc.)
1374 {
1375 refresh_all_group_centers(); // since we don't know which group of control vertices v is erased from, refresh all
1376 return true;
1377 }
1378
1379 print_message("Selected vertex is not a control vertex!");
1380 return false;
1381 }
1382 template<typename Mesh>
erase_roi_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v,Mesh * mesh)1383 bool Scene_edit_polyhedron_item::erase_roi_vertex(typename boost::graph_traits<Mesh>::vertex_descriptor v, Mesh* mesh)
1384 {
1385
1386 erase_control_vertex(v, mesh); // erase control vertex
1387 Facegraph_selector fs(d);
1388 return fs.get_deform_mesh(mesh)->erase_roi_vertex(v);
1389 }
1390
clear_roi()1391 void Scene_edit_polyhedron_item::clear_roi()
1392 {
1393 for(Ctrl_vertices_sm_group_data_list::iterator it = d->sm_ctrl_vertex_frame_map.begin(); it != d->sm_ctrl_vertex_frame_map.end(); ++it)
1394 {
1395 delete it->frame;
1396 }
1397 d->sm_ctrl_vertex_frame_map.clear();
1398 d->deform_sm_mesh->clear_roi_vertices();
1399 create_ctrl_vertices_group(); // create one new group of control vertices
1400
1401 }
1402
create_ctrl_vertices_group()1403 void Scene_edit_polyhedron_item::create_ctrl_vertices_group()
1404 {
1405 for(Ctrl_vertices_sm_group_data_list::iterator it = d->sm_ctrl_vertex_frame_map.begin(); it != d->sm_ctrl_vertex_frame_map.end(); ++it) {
1406 if(it->ctrl_vertices_group.empty()) {
1407 d->sm_active_group = it;
1408 return;
1409 }
1410 }
1411 // No empty group of control vertices
1412 const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset();
1413 CGAL::qglviewer::ManipulatedFrame* new_frame = new CGAL::qglviewer::ManipulatedFrame();
1414 new_frame->setPosition(offset);
1415 new_frame->setRotationSensitivity(2.0f);
1416 new_frame->setSpinningSensitivity(1000);
1417 connect(new_frame, SIGNAL(manipulated()), this, SLOT(change()));
1418 Control_vertices_data<SMesh> hgd(d->deform_sm_mesh, new_frame);
1419 d->sm_ctrl_vertex_frame_map.push_back(hgd);
1420 hgd.refresh(surface_mesh());
1421
1422 d->sm_active_group = --d->sm_ctrl_vertex_frame_map.end();
1423
1424 invalidateOpenGLBuffers();
1425 Q_EMIT itemChanged();
1426
1427 print_message("A new empty group of control vertices is created.");
1428 }
1429
1430 template<typename Mesh>
delete_ctrl_vertices_group(Mesh * mesh,bool create_new)1431 void Scene_edit_polyhedron_item_priv::delete_ctrl_vertices_group(Mesh* mesh, bool create_new)
1432 {
1433 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
1434 if(!item->is_there_any_ctrl_vertices_group()) {
1435 item->print_message("There is no group of control vertices to be deleted!");
1436 return;
1437 } // no group of control vertices
1438 Facegraph_selector fs(this);
1439 // delete group representative
1440 for(typename std::list<Control_vertices_data<Mesh> >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it)
1441 {
1442 if(it == fs.get_active_group(mesh))
1443 {
1444 delete it->frame;
1445 for(typename std::vector<mesh_vd>::iterator v_it = it->ctrl_vertices_group.begin(); v_it != it->ctrl_vertices_group.end(); ++v_it) {
1446 fs.get_deform_mesh(mesh)->erase_control_vertex(*v_it);
1447 }
1448 fs.get_ctrl_vertex_frame_map(mesh).erase(it);
1449 break;
1450 }
1451 }
1452
1453 // assign another ctrl_vertices_group to active_group
1454 typename std::list<Control_vertices_data<Mesh> >::iterator hgb, hge;
1455 if( item->is_there_any_ctrl_vertices_group(hgb, hge) )
1456 {
1457 fs.get_active_group(mesh) = hgb;
1458 } // no group of control vertices
1459 else if(create_new)
1460 {
1461 item->create_ctrl_vertices_group();
1462 }
1463 }
1464
prev_ctrl_vertices_group()1465 void Scene_edit_polyhedron_item::prev_ctrl_vertices_group()
1466 {
1467 Ctrl_vertices_sm_group_data_list::iterator hgb, hge;
1468 if( !is_there_any_ctrl_vertices_group(hgb, hge) ) {
1469 print_message("There is no group of control vertices to iterate on!");
1470 return;
1471 }
1472 // shift
1473 if(hgb == d->sm_active_group) { d->sm_active_group = --hge; }
1474 else {--d->sm_active_group; }
1475 }
1476
next_ctrl_vertices_group()1477 void Scene_edit_polyhedron_item::next_ctrl_vertices_group()
1478 {
1479 Ctrl_vertices_sm_group_data_list::iterator hgb, hge;
1480 if( !is_there_any_ctrl_vertices_group(hgb, hge) ) {
1481 print_message("There is no group of control vertices to iterate on!");
1482 return;
1483 }
1484 // shift
1485 if(--hge == d->sm_active_group) { d->sm_active_group = hgb; }
1486 else {++d->sm_active_group; }
1487 }
1488
pivoting_begin()1489 void Scene_edit_polyhedron_item::pivoting_begin()
1490 {
1491 d->pivoting_begin(surface_mesh());
1492 }
1493
pivoting_end()1494 void Scene_edit_polyhedron_item::pivoting_end()
1495 {
1496 d->pivoting_end(surface_mesh());
1497 }
1498
1499 template<typename Mesh>
pivoting_end(Mesh * mesh)1500 void Scene_edit_polyhedron_item_priv::pivoting_end(Mesh* mesh)
1501 {
1502 Facegraph_selector fs(this);
1503 for(typename std::list<Control_vertices_data<Mesh> >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it)
1504 {
1505 //update constraint rotation vector, set only for the last group
1506 it->rot_direction = it->frame->rotation().rotate( CGAL::qglviewer::Vec(0.,0.,1.) );
1507 //translate center of the frame
1508 const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset();
1509 CGAL::qglviewer::Vec vec= it->frame->position();
1510 CGAL::qglviewer::Quaternion orientation = it->frame->orientation();
1511 it->refresh(mesh);
1512 it->frame_initial_center = vec-offset;
1513 it->frame->setPosition(vec);
1514 it->frame->setOrientation(orientation);
1515 it->frame->blockSignals(false);
1516 }
1517 }
1518
1519 template<typename Mesh>
pivoting_begin(Mesh * mesh)1520 void Scene_edit_polyhedron_item_priv::pivoting_begin(Mesh* mesh)
1521 {
1522 is_rot_free=true;
1523 rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
1524 rot_constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
1525
1526 // just block signals to prevent deformation
1527 Facegraph_selector fs(this);
1528 for(typename std::list<Control_vertices_data<Mesh> >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it)
1529 {
1530 it->frame->blockSignals(true);
1531 }
1532 }
1533
save_roi(const char * file_name) const1534 void Scene_edit_polyhedron_item::save_roi(const char* file_name) const
1535 {
1536 std::ofstream out(file_name);
1537 // save roi
1538 Id_setter id_getter(d->sm_item->polyhedron());
1539 out << d->deform_sm_mesh->roi_vertices().size() << std::endl;
1540 for(sm_vertex_descriptor vd : d->deform_sm_mesh->roi_vertices())
1541 {
1542 out << id_getter.get_id(vd) << " ";
1543 }
1544 out << std::endl;
1545 // save control vertices
1546 out << d->sm_ctrl_vertex_frame_map.size() << std::endl; // control vertices count
1547 for(Ctrl_vertices_sm_group_data_list::const_iterator hgb = d->sm_ctrl_vertex_frame_map.begin(); hgb != d->sm_ctrl_vertex_frame_map.end(); ++hgb) {
1548
1549 out << hgb->ctrl_vertices_group.size() << std::endl;
1550 for(std::vector<sm_vertex_descriptor>::const_iterator hb = hgb->ctrl_vertices_group.begin(); hb != hgb->ctrl_vertices_group.end(); ++hb)
1551 {
1552 out << id_getter.get_id(*hb) << " ";
1553 }
1554 out << std::endl;
1555 }
1556 }
1557
1558 template<typename Mesh>
read_roi(const char * file_name,Mesh * mesh)1559 void Scene_edit_polyhedron_item_priv::read_roi(const char* file_name, Mesh* mesh)
1560 {
1561 typedef typename boost::graph_traits<Mesh>::vertex_descriptor mesh_vd;
1562 typedef typename boost::graph_traits<Mesh>::vertex_iterator mesh_vi;
1563
1564 Facegraph_selector fs(this);
1565 delete_ctrl_vertices_group(mesh, false);
1566 // put vertices to vector
1567 std::vector<mesh_vd> all_vertices;
1568 all_vertices.reserve(num_vertices(fs.get_deform_mesh(mesh)->halfedge_graph()));
1569 mesh_vi vb, ve;
1570 for(boost::tie(vb, ve) = vertices(fs.get_deform_mesh(mesh)->halfedge_graph()); vb != ve; ++vb) {
1571 all_vertices.push_back(*vb);
1572 }
1573 // read roi
1574 std::ifstream in(file_name);
1575 int roi_size;
1576 in >> roi_size;
1577 while(roi_size-- > 0)
1578 {
1579 std::size_t v_id;
1580 in >> v_id;
1581 item->insert_roi_vertex<Mesh>(all_vertices[v_id], mesh);
1582
1583 }
1584 // read control vertices
1585 int ctrl_vertices_group_size;
1586 in >> ctrl_vertices_group_size;
1587 while(ctrl_vertices_group_size-- > 0)
1588 {
1589 item->create_ctrl_vertices_group();
1590 int ctrl_size;
1591 in >> ctrl_size;
1592 while(ctrl_size-- > 0)
1593 {
1594 std::size_t v_id;
1595 in >> v_id;
1596 item->insert_control_vertex<Mesh>(all_vertices[v_id], mesh);
1597 }
1598 }
1599 }
1600
read_roi(const char * file_name)1601 void Scene_edit_polyhedron_item::read_roi(const char* file_name)
1602 {
1603 d->read_roi(file_name, surface_mesh());
1604 }
1605
overwrite_deform_object()1606 void Scene_edit_polyhedron_item::overwrite_deform_object()
1607 {
1608 d->deform_sm_mesh->overwrite_initial_geometry();
1609
1610 refresh_all_group_centers();
1611 }
1612
reset_deform_object()1613 void Scene_edit_polyhedron_item::reset_deform_object()
1614 {
1615 d->deform_sm_mesh->reset();
1616 refresh_all_group_centers();
1617 }
1618
get_minimum_isolated_component()1619 boost::optional<std::size_t> Scene_edit_polyhedron_item::get_minimum_isolated_component() {
1620 Travel_isolated_components<SMesh>::Minimum_visitor visitor;
1621 Travel_isolated_components<SMesh>(*surface_mesh()).travel<sm_vertex_descriptor>
1622 (vertices(*surface_mesh()).first, vertices(*surface_mesh()).second,
1623 num_vertices(*surface_mesh()), Is_selected<SMesh>(d->deform_sm_mesh), visitor);
1624 return visitor.minimum;
1625 }
1626
1627
select_isolated_components(std::size_t threshold)1628 boost::optional<std::size_t> Scene_edit_polyhedron_item::select_isolated_components(std::size_t threshold) {
1629 typedef boost::function_output_iterator<Select_roi_output<SMesh> > Output_iterator;
1630 Output_iterator out(d->deform_sm_mesh);
1631
1632 Travel_isolated_components<SMesh>::Selection_visitor<Output_iterator> visitor(threshold, out);
1633 Travel_isolated_components<SMesh>(*surface_mesh()).travel<sm_vertex_descriptor>
1634 (vertices(*surface_mesh()).first, vertices(*surface_mesh()).second,
1635 num_vertices(*surface_mesh()), Is_selected<SMesh>(d->deform_sm_mesh), visitor);
1636
1637 if(visitor.any_inserted) { invalidateOpenGLBuffers(); Q_EMIT itemChanged(); }
1638 return visitor.minimum_visitor.minimum;
1639 }
1640
is_there_any_ctrl_vertices_group()1641 bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices_group()
1642 {
1643 if(d->sm_item)
1644 {
1645 Ctrl_vertices_sm_group_data_list::iterator hgb, hge;
1646 return is_there_any_ctrl_vertices_group(hgb, hge);
1647 }
1648 return false;
1649 }
1650
is_there_any_ctrl_vertices()1651 bool Scene_edit_polyhedron_item::is_there_any_ctrl_vertices()
1652 {
1653 Ctrl_vertices_sm_group_data_list::iterator hgb, hge;
1654 if(!is_there_any_ctrl_vertices_group(hgb, hge)) { return false; } // there isn't any group of control vertices
1655
1656 for(; hgb != hge; ++hgb) // check inside groups of control vertices
1657 {
1658 if(!hgb->ctrl_vertices_group.empty()) { return true; }
1659 }
1660 return false;
1661 }
1662
refresh_all_group_centers()1663 void Scene_edit_polyhedron_item::refresh_all_group_centers()
1664 {
1665 for(Ctrl_vertices_sm_group_data_list::iterator it = d->sm_ctrl_vertex_frame_map.begin(); it != d->sm_ctrl_vertex_frame_map.end(); ++it)
1666 { it->refresh(surface_mesh()); }
1667 }
1668
1669 template<typename Mesh>
activate_closest_manipulated_frame(int x,int y,Mesh * mesh)1670 bool Scene_edit_polyhedron_item::activate_closest_manipulated_frame(int x, int y, Mesh* mesh)
1671 {
1672 Facegraph_selector fs(d);
1673 if(d->state.ctrl_pressing && (d->state.left_button_pressing || d->state.right_button_pressing) )
1674 { // user is deforming currently don't change the state
1675 return false;
1676 }
1677 if(fs.get_ctrl_vertex_frame_map(mesh).empty()) { return false; }
1678
1679 d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
1680 d->rot_constraint.setTranslationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FREE);
1681
1682 CGAL::QGLViewer* viewer = Three::mainViewer();
1683 CGAL::qglviewer::Camera* camera = viewer->camera();
1684
1685 if(!d->state.ctrl_pressing)
1686 {
1687 if(viewer->manipulatedFrame() == nullptr)
1688 { return false;}
1689 viewer->setManipulatedFrame(nullptr);
1690 return true;
1691 }
1692
1693 // now find closest frame and make it active manipulated frame
1694 typename std::list<Control_vertices_data<Mesh> >::iterator min_it = fs.get_ctrl_vertex_frame_map(mesh).begin();
1695 const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(min_it->frame->position());
1696 float min_dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2);
1697
1698 for(typename std::list<Control_vertices_data<Mesh> >::iterator it = fs.get_ctrl_vertex_frame_map(mesh).begin(); it != fs.get_ctrl_vertex_frame_map(mesh).end(); ++it)
1699 {
1700 const CGAL::qglviewer::Vec& pos_it = camera->projectedCoordinatesOf(it->frame->position());
1701 float dist = std::pow(pos_it.x - x, 2) + std::pow(pos_it.y - y, 2);
1702 if(dist < min_dist) {
1703 min_dist = dist;
1704 min_it = it;
1705 }
1706 }
1707
1708 //set rotation constraint for the manipulated frame
1709 if (!d->is_rot_free){
1710 d->rot_constraint.setRotationConstraintDirection(min_it->rot_direction);
1711 d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::AXIS);
1712 min_it->frame->setConstraint(&d->rot_constraint);
1713 }
1714 else
1715 {
1716 if( d->ui_widget->ActivateFixedPlaneCheckBox->isChecked())
1717 {
1718 // the constraint is local to the frame
1719 d->rot_constraint.setTranslationConstraint(CGAL::qglviewer::AxisPlaneConstraint::PLANE,CGAL::qglviewer::Vec(0,0,1));
1720 if(!d->ui_widget->ActivatePivotingCheckBox->isChecked()){
1721 d->rot_constraint.setRotationConstraintType(CGAL::qglviewer::AxisPlaneConstraint::FORBIDDEN);
1722 }
1723 min_it->frame->setConstraint(&d->rot_constraint);
1724 }
1725 }
1726
1727 if(viewer->manipulatedFrame() == min_it->frame)
1728 { return false; }
1729 viewer->setManipulatedFrame(min_it->frame);
1730 fs.get_active_group(mesh) = min_it;
1731 return true;
1732 }
1733
update_normals()1734 void Scene_edit_polyhedron_item::update_normals() {
1735 for(sm_vertex_descriptor vd : d->deform_sm_mesh->roi_vertices())
1736 {
1737 std::size_t id = id_setter->get_id(vd);
1738 const EPICK::Vector_3& n =
1739 CGAL::Polygon_mesh_processing::compute_vertex_normal(vd, d->deform_sm_mesh->halfedge_graph());
1740 d->normals[id*3] = n.x();
1741 d->normals[id*3+1] = n.y();
1742 d->normals[id*3+2] = n.z();
1743
1744 }
1745 }
1746
1747
set_all_vertices_as_roi()1748 void Scene_edit_polyhedron_item::set_all_vertices_as_roi()
1749 {
1750 boost::graph_traits<SMesh>::vertex_iterator vb, ve;
1751 for(boost::tie(vb, ve) = vertices(*surface_mesh()); vb != ve; ++vb)
1752 {
1753 insert_roi_vertex<SMesh>(*vb, surface_mesh());
1754 }
1755 }
1756
delete_ctrl_vertices_group(bool create_new)1757 void Scene_edit_polyhedron_item::delete_ctrl_vertices_group(bool create_new)
1758 {
1759 d->delete_ctrl_vertices_group(surface_mesh(), create_new);
1760
1761 }
1762
insert_roi_vertex(sm_vertex_descriptor vh)1763 bool Scene_edit_polyhedron_item::insert_roi_vertex(sm_vertex_descriptor vh)
1764 {
1765
1766 return insert_roi_vertex<SMesh>(vh, surface_mesh());
1767 }
1768
sm_item() const1769 Scene_surface_mesh_item* Scene_edit_polyhedron_item::sm_item()const
1770 {
1771 return d->sm_item;
1772 }
1773
computeElements() const1774 void Scene_edit_polyhedron_item::computeElements() const
1775 {
1776 d->compute_normals_and_vertices(sm_item()->face_graph());
1777 if(d->spheres)
1778 d->spheres->computeElements();
1779 if(d->spheres_ctrl)
1780 d->spheres_ctrl->computeElements();
1781 std::vector<GLfloat> vertices;
1782 std::vector<GLfloat> *vertices_ptr;
1783 const CGAL::qglviewer::Vec offset = Three::mainViewer()->offset();
1784 if(offset.norm() !=0)
1785 {
1786 vertices.resize(d->positions.size());
1787 for(std::size_t i=0; i<d->positions.size(); ++i)
1788 {
1789 (vertices)[i] = d->positions[i]+offset[i%3];
1790 }
1791 vertices_ptr = &vertices;
1792 }
1793 else
1794 {
1795 vertices_ptr = &d->positions;
1796 }
1797 //vao for the facets
1798 {
1799 Tc* tc = getTriangleContainer(Priv::Facets);
1800 tc->allocate(
1801 Tc::Smooth_vertices,
1802 vertices_ptr->data(),
1803 static_cast<int>(vertices_ptr->size()*sizeof(float)));
1804 tc->allocate(
1805 Tc::Smooth_normals,
1806 d->normals.data(),
1807 static_cast<int>(d->normals.size()*sizeof(float)));
1808 tc->allocate(
1809 Tc::Vertex_indices,
1810 d->tris.data(),
1811 static_cast<int>(d->tris.size()*sizeof(float)));
1812 }
1813 //vao for the ROI points
1814 {
1815 Pc* pc = getPointContainer(Priv::Roi_points);
1816 pc->allocate(
1817 Pc::Vertices,
1818 d->ROI_points.data(),
1819 static_cast<int>(d->ROI_points.size()*sizeof(float)));
1820 d->nb_ROI = d->ROI_points.size();
1821 }
1822 //vao for the edges
1823 {
1824 Ec* ec = getEdgeContainer(Priv::Edges);
1825 ec->allocate(
1826 Ec::Vertices,
1827 vertices_ptr->data(),
1828 static_cast<int>(vertices_ptr->size()*sizeof(float)));
1829 ec->allocate(
1830 Ec::Indices,
1831 d->_edges.data(),
1832 static_cast<int>(d->_edges.size()*sizeof(float)));
1833 }
1834 //vao for the BBOX
1835 {
1836 Ec* ec = getEdgeContainer(Priv::BBox);
1837 ec->allocate(Ec::Vertices,
1838 d->pos_bbox.data(),
1839 static_cast<int>(d->pos_bbox.size()*sizeof(float)));
1840
1841 d->nb_bbox = d->pos_bbox.size();
1842 }
1843 //vao for the control points
1844 {
1845 Pc* pc = getPointContainer(Priv::Control_points);
1846 pc->allocate(Pc::Vertices,
1847 d->control_points.data(),
1848 static_cast<int>(d->control_points.size()*sizeof(float)));
1849
1850 pc->allocate(Pc::Colors,
1851 d->control_color.data(),
1852 static_cast<int>(d->control_color.size()*sizeof(float)));
1853
1854
1855 d->nb_control = d->control_points.size();
1856 }
1857 //vao for the axis
1858 {
1859 Ec* ec = getEdgeContainer(Priv::Axis);
1860 ec->allocate(
1861 Ec::Vertices,
1862 d->pos_axis.data(),
1863 static_cast<int>(d->pos_axis.size()*sizeof(float)));
1864 ec->allocate(Ec::Colors,
1865 d->color_lines.data(),
1866 static_cast<int>(d->color_lines.size()*sizeof(float)));
1867 d->nb_axis = d->pos_axis.size();
1868
1869 }
1870 //vao for the frame plane
1871 {
1872
1873 Tc* tc = getTriangleContainer(Priv::Frame_plane);
1874 tc->allocate(Tc::Smooth_vertices,
1875 d->pos_frame_plane.data(),
1876 static_cast<int>(d->pos_frame_plane.size()*sizeof(float)));
1877 tc->allocate(Tc::Vertex_indices,
1878 d->plane_idx.data(),
1879 static_cast<int>(d->plane_idx.size()*sizeof(float)));
1880 }
1881 setBuffersFilled(true);
1882 }
1883
initializeBuffers(Viewer_interface * v) const1884 void Scene_edit_polyhedron_item::initializeBuffers(Viewer_interface *v) const
1885 {
1886 getTriangleContainer(Priv::Facets)->initializeBuffers(v);
1887 getTriangleContainer(Priv::Frame_plane)->initializeBuffers(v);
1888 getEdgeContainer(Priv::Edges)->initializeBuffers(v);
1889 getEdgeContainer(Priv::Axis)->initializeBuffers(v);
1890 getEdgeContainer(Priv::BBox)->initializeBuffers(v);
1891 getPointContainer(Priv::Roi_points)->initializeBuffers(v);
1892 getPointContainer(Priv::Control_points)->initializeBuffers(v);
1893
1894 getTriangleContainer(Priv::Facets)->setIdxSize(d->tris.size());
1895 getTriangleContainer(Priv::Frame_plane)->setIdxSize(d->plane_idx.size());
1896 getEdgeContainer(Priv::Edges)->setIdxSize(d->_edges.size());
1897 getEdgeContainer(Priv::Axis)->setFlatDataSize(d->nb_axis);
1898 getEdgeContainer(Priv::BBox)->setFlatDataSize(d->nb_bbox);
1899 getPointContainer(Priv::Roi_points)->setFlatDataSize(d->nb_ROI);
1900 getPointContainer(Priv::Control_points)->setFlatDataSize(d->nb_control);
1901
1902 d->pos_axis.resize(0);
1903 d->pos_axis.shrink_to_fit();
1904 d->color_lines.resize(0);
1905 d->color_lines.shrink_to_fit();
1906 d->control_points.clear();
1907 d->control_points.shrink_to_fit();
1908 d->pos_bbox.resize(0);
1909 d->pos_bbox.shrink_to_fit();
1910 d->ROI_points.clear();
1911 d->ROI_points.shrink_to_fit();
1912 }
1913
init(Vi * viewer) const1914 void Scene_edit_polyhedron_item::init(Vi* viewer)const
1915 {
1916 if(!isInit(viewer))
1917 initGL(viewer);
1918 if ( getBuffersFilled() &&
1919 ! getBuffersInit(viewer))
1920 {
1921 initializeBuffers(viewer);
1922 setBuffersInit(viewer, true);
1923 }
1924 if(!getBuffersFilled())
1925 {
1926 computeElements();
1927 initializeBuffers(viewer);
1928 }
1929 }
1930