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 &center) 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 &center) 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