MEPP2 Project
Batch_decompressor.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2022 University of Lyon and CNRS (France).
2 // All rights reserved.
3 //
4 // This file is part of MEPP2; you can redistribute it and/or modify
5 // it under the terms of the GNU Lesser General Public License as
6 // published by the Free Software Foundation; either version 3 of
7 // the License, or (at your option) any later version.
8 //
9 // This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
10 // WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
11 
12 #pragma once
13 
14 #include <boost/graph/graph_traits.hpp>
15 #include <boost/graph/properties.hpp>
16 
18 
19 #include "CGAL/boost/graph/Euler_operations.h"
20 
21 
24 
26 
30 
32 
35 
36 #include "FEVV/Filters/CGAL/Progressive_Compression/Geometric_metrics.h" // needed for the compilation
37 
40 
41 #include "FEVV/DataStructures/DataStructures_cgal_linear_cell_complex.h" // to test is_isomorphic_to method
44 
45 
46 #include <fstream>
47 #include <iostream>
48 #include <vector>
49 #include <list>
50 #include <map>
51 #include <utility>
52 
53 namespace FEVV {
54 namespace Filters {
55 
56 enum class TOPOLOGY_CASE {
57 
58  CASE11 = 0,
59  CASE12,
60  CASE13,
61  CASE211,
62  CASE212,
63  CASE221,
64  CASE222,
65  SIMPLE
66 };
67 
68 
69 
74 template< typename HalfedgeGraph,
75  typename PointMap,
76  typename VertexColorMap >
78 {
79 
80 
81 public:
85  typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor;
87  typename boost::graph_traits< HalfedgeGraph >::face_descriptor;
91 
107  HalfedgeGraph &g,
108  PointMap &pm,
110  FEVV::Filters::Kept_position< HalfedgeGraph,
111  PointMap,
112  Geometry > *vkept,
113  const FEVV::Header_handler &header,
114  VertexColorMap &vcm)
115  : _g(g), _pm(pm), _gt(Geometry(g)), _predictor(predictor), _vkept(vkept),
116  _header(header), _vcm(vcm)
117  {
118  _batch_id = 0;
119  }
121 
130  void predict_positions(const std::list< halfedge_descriptor > &h_extent,
131  std::list< std::pair< Point, Point > > &new_points)
132  {
133 
134  auto pos_it = _positions.begin();
135  auto info_it = _other_info_bits.begin(); // reverse information
136  for(typename std::list< halfedge_descriptor >::const_iterator h_it =
137  h_extent.begin();
138  h_it != h_extent.end();
139  h_it++)
140  {
141  halfedge_descriptor hnew;
142  halfedge_descriptor h1 = *h_it;
143  h_it++;
144  halfedge_descriptor h2 = *h_it;
145 
146  vertex_descriptor vkept = target(h1, _g);
147 
148  if(_vkept->get_type() == VKEPT_POSITION::HALFEDGE)
149  {
150  bool b = (*info_it);
151 
152  _predictor->set_rev(b);
153  info_it++;
154  }
155 
156  std::pair< Point, Point > resulting_points =
157  _predictor->place_points(*pos_it, vkept, h1, h2);
158  pos_it++;
159  new_points.push_back(std::move(resulting_points));
160  }
161  }
162 
166  PointMap >
167  &spanningtree)
168  {
169  std::ofstream file_encode;
170  file_encode.open("decodingspanning" + std::to_string(_batch_id) + ".txt");
171  auto span = spanningtree.get_spanning_tree_vertices();
172  typename std::list< vertex_descriptor >::const_iterator it = span.begin();
173 
174  for( ; it != span.end(); it++)
175  {
176  const Point& pt = get(_pm, *it);
177  std::list< vertex_descriptor > list_v_around =
179  file_encode << _gt.get_x(pt) << " " << _gt.get_y(pt) << " "
180  << _gt.get_z(pt) << " " << list_v_around.size() << std::endl;
181  }
182  file_encode.close();
183  }
184 
189  {
191  _g,
192  _pm,
196 
198  }
199 
207  void decompress_binary_batch(draco::DecoderBuffer &buffer)
208  {
209  // Decode data for a batch.
210  Binary_batch_decoder< HalfedgeGraph,
211  PointMap,
212  Vector >
213  decoder(buffer, _header.get_quantization());
214  decoder.decode_bitmask(_bitmask); // Implements line 5 of Algorithm 2.
215  decoder.decode_bitmask(_edge_bitmask); // Implements line 6 of Algorithm 2.
216 
217  // Implements lines 7 to 9 of Algorithm 2.
218  if (_vkept->get_type() == FEVV::Filters::VKEPT_POSITION::HALFEDGE)
219  { // For HALFEDGE/target case, an additional bit information is
220  // needed
221  decoder.decode_bitmask(_other_info_bits); // Implements line 8 of Algorithm 2.
222  }
223 
224  // Implements line 10 of Algorithm 2.
225  decoder.decode_residuals(_positions, _predictor->get_nb_residuals());
227  // Predict position and refine mesh from the decoded data
228 
229  // Build a spanning tree for halfedge graph _g with vertex positions in _pm
230  // Implements line 11 of Algorithm 2.
231  FEVV::Comparator::
232  Spanning_tree_vertex_edge_comparator< HalfedgeGraph, PointMap, Geometry >
233  spanningtree(_g, _pm, true);// "true"(=tie-break detection and avoidance)
234  // as for Batch_collapser to get
235  // the same adjacency ordering (and not
236  // too costly for reasonable
237  // quantization)
239  std::list< halfedge_descriptor > h_extent;
240  // Find every halfedge we have to expand into faces.
241  fill_h_extent_list_no_sort(spanningtree, h_extent); // Implements line 12 of
242  // Algorithm 2.
243  // Split corresponding vertices
244  split_vertices(h_extent); // Implements lines 13 to 19 of Algorithm 2.
245 
246  std::cout << "batch " << std::to_string(_batch_id) << " done" << std::endl;
247  _batch_id++;
248  _bitmask.clear();
249  _edge_bitmask.clear();
250  _positions.clear();
251  _other_info_bits.clear();
252  }
253 
254 private:
255  HalfedgeGraph &_g;
256  PointMap &_pm;
257  const Geometry _gt;
258  std::vector< std::vector< bool > > neighbours_bitmasks;
260 
261  FEVV::Filters::
262  Predictor< HalfedgeGraph, PointMap >
264  FEVV::Filters::Kept_position< HalfedgeGraph,
265  PointMap,
267 
268  std::list< std::vector< Vector > > _positions;
269 
270  std::list< bool > _bitmask;
271  std::list< bool > _edge_bitmask;
272  std::list< bool > _other_info_bits;
273  const FEVV::Header_handler &_header; // quantization info is obtained via the
274  // header
275  VertexColorMap &_vcm;
276 
278  bool split_vertices(const std::list< halfedge_descriptor > &h_extent)
279  {
281  // DECODE VERTEX POSITIONS FOR ALL VERTICES TO SPLIT //
283  std::list< std::pair< Point, Point > > new_points;
284  predict_positions(h_extent, new_points); // Implements line 13 of Algorithm 2.
285  auto pos_it = _positions.begin();
286  auto info_it = _other_info_bits.begin();
288  // APPLY VERTEX SPLITS //
290  // Implements lines 14 to 19 of Algorithm 2:
291  auto new_points_it = new_points.begin();
292  for(typename std::list< halfedge_descriptor >::const_iterator h_it =
293  h_extent.begin();
294  h_it != h_extent.end();
295  h_it++)
296  {
297  halfedge_descriptor hnew;
298  halfedge_descriptor h1 = *h_it;
299  h_it++;
300  halfedge_descriptor h2 = *h_it;
301 
302  TOPOLOGY_CASE current_case = find_case(h1, h2);
303 
304  bool reverse = false;
305  if(_vkept->get_type() == VKEPT_POSITION::HALFEDGE)
306  {
307  bool b = (*info_it);
308 
309  _predictor->set_rev(b);
310  reverse = b;
311  info_it++;
312  }
313 
314  std::pair< Point, Point > resulting_points = *new_points_it;
315  new_points_it++;
316 
317  if(current_case == TOPOLOGY_CASE::SIMPLE)
318  {
319  hnew = simple_split_sase(h1, h2);
320  }
321  else
322  {
323  if(current_case == TOPOLOGY_CASE::CASE211 ||
324  current_case == TOPOLOGY_CASE::CASE212 ||
325  current_case == TOPOLOGY_CASE::CASE221 ||
326  current_case == TOPOLOGY_CASE::CASE222)
327  {
328  hnew = cases_2(h1, h2, current_case);
329  }
330  else
331  {
332 
333  hnew = cases_1(h1, current_case);
334  }
335  }
336  put(_pm, target(hnew, _g), resulting_points.first);
337  put(_pm, source(hnew, _g), resulting_points.second);
338 
339  if(pos_it != _positions.end())
340  {
341  pos_it++;
342  }
343  }
344 
345  return true;
346  }
347 
353  const FEVV::Comparator::
354  Spanning_tree_vertex_edge_comparator< HalfedgeGraph, PointMap, Geometry >
355  &spanningtree,
356  std::list< halfedge_descriptor > &h_extent)
357 
358  {
359  const std::list< vertex_descriptor >& spanning_vertices =
360  spanningtree.get_spanning_tree_vertices();
361 
362  // get iterators on topology bitmasks
363 
364  // Bitmask indicating whether we split a vertex or not
365  std::list< bool >::iterator bit_it = _bitmask.begin();
366  std::list< bool >::iterator bit_it_end = _bitmask.end();
367 
368 
369  // Btmask indicating the halfedges to expand around a vertex to be split
370  std::list< bool >::iterator edge_bit_it = _edge_bitmask.begin();
371  std::list< bool >::iterator edge_bit_it_end = _edge_bitmask.end();
372 
373  typename std::list< vertex_descriptor >::const_iterator spanning_it =
374  spanning_vertices.begin();
375  std::list< vertex_descriptor > vsplit_neighbours_list;
376 
377  // bit optimization stuff (to not encode predictable zeros)
378  bool last_was_1 = false;
379  std::list< vertex_descriptor > remaining_adjacent_vertices_of_last_v, tmp;
380  std::map<vertex_descriptor, bool> processed_vertices;
381 
382  // Iterate through the vertices in the order of the spanning tree
383  for(; bit_it != bit_it_end; spanning_it++)
384  {
385  // bit optimization stuff (to not encode predictable zeros)
386  processed_vertices[*spanning_it] = true;
387  bool is_adjacent_to_former_1 = false;
388  if(last_was_1)
389  {
390  auto it_to_remove = std::find(remaining_adjacent_vertices_of_last_v.begin(),
391  remaining_adjacent_vertices_of_last_v.end(), *spanning_it) ;
392  is_adjacent_to_former_1 = (it_to_remove != remaining_adjacent_vertices_of_last_v.end());
393  if(is_adjacent_to_former_1)
394  remaining_adjacent_vertices_of_last_v.erase(it_to_remove);
395  if(remaining_adjacent_vertices_of_last_v.empty())
396  last_was_1 = false;
397  }
398 
399  // if we have to split the current vertex
400  if((*bit_it == true) && !is_adjacent_to_former_1)
401  {
402  // bit optimization stuff
403  last_was_1 = true;
404  tmp = FEVV::Comparator::get_not_processed_adjacent_vertices(*spanning_it, _g, processed_vertices, spanningtree.get_spanning_tree_min_incident_edge(*spanning_it));
405  remaining_adjacent_vertices_of_last_v.insert(remaining_adjacent_vertices_of_last_v.end(), tmp.begin(), tmp.end());
406 
407  // find min edge
408  std::vector< bool > current_edge_bit;
409  auto e_min_tree = spanningtree.get_spanning_tree_min_incident_edge(*spanning_it);
410  halfedge_descriptor h_min_tree = halfedge(e_min_tree, _g);
411  if(target(h_min_tree, _g) != *spanning_it)
412  h_min_tree = opposite(h_min_tree, _g);
413  halfedge_descriptor current_edge = h_min_tree;
414  int nb_edges = 0;
415  do
416  {
417  // find the halfedges to extent (0: don't extend, 1: extend)
418  if(nb_edges>1)
419  current_edge_bit.push_back(false);
420  else
421  {
422  current_edge_bit.push_back(*edge_bit_it);
423  if(*edge_bit_it == true)
424  {
425  // if 1, we add the halfedge to the list
426  h_extent.push_back(current_edge);
427  nb_edges += 1;
428  }
429  edge_bit_it++;
430  }
431  // run around the current vertex
432  current_edge = opposite(next(current_edge, _g), _g);
433  } while(current_edge != h_min_tree &&
434  edge_bit_it != edge_bit_it_end);
435  neighbours_bitmasks.push_back(current_edge_bit);
436  if(nb_edges == 1)
437  {
438  h_extent.push_back(h_extent.back());
439  }
440 
441  if(nb_edges != 1 && nb_edges != 2)
442  {
443  std::cerr << "fill_h_extent_list_no_sort: error. No halfedge to extent." << std::endl;
444  }
445 
446  vsplit_neighbours_list.clear();
447 
448  bit_it++;
449  }
450  else if(!is_adjacent_to_former_1)
451  bit_it++;
452  }
453  }
454 
457  {
458  if(h1 == h2)
459  {
460  halfedge_descriptor h = h1;
461  halfedge_descriptor opp_h = opposite(h, _g);
462  if(!(CGAL::is_border(h, _g)) &&
463  !(!CGAL::is_border(
464  opp_h,
465  _g))) // both halfedges are not border, but a vertex might be
466  {
467  return TOPOLOGY_CASE::CASE11;
468  }
469  else
470  {
471  if(!CGAL::is_border(h, _g) &&
472  CGAL::is_border(opp_h, _g)) // opposite on border
473  {
474  return TOPOLOGY_CASE::CASE12;
475  }
476  else
477  {
478  return TOPOLOGY_CASE::CASE13;
479  }
480  }
481  }
482  else
483  {
484  if((face(h1, _g) != boost::graph_traits< HalfedgeGraph >::null_face()) &&
485  (face(h2, _g) !=
486  boost::graph_traits<
487  HalfedgeGraph >::null_face())) // both edges completely internal
488  {
489  return TOPOLOGY_CASE::SIMPLE;
490  }
491  else
492  {
493  if(face(h1, _g) == boost::graph_traits< HalfedgeGraph >::null_face())
494  {
495  if(face(opposite(h2, _g), _g) ==
496  boost::graph_traits< HalfedgeGraph >::null_face())
497  {
498  return TOPOLOGY_CASE::CASE211;
499  }
500  else
501  {
502  return TOPOLOGY_CASE::CASE221;
503  }
504  }
505  else
506  {
507  if(face(opposite(h1, _g), _g) ==
508  boost::graph_traits< HalfedgeGraph >::null_face())
509  {
510  return TOPOLOGY_CASE::CASE212;
511  }
512  else
513  {
514  return TOPOLOGY_CASE::CASE222;
515  }
516  }
517  }
518  }
519  }
520 
523  halfedge_descriptor h2) // Simple Split Case: both h1 and h2 are internal
524  // to the mesh, and none is linked to a null face
525  {
526  if((face(h1, _g) != boost::graph_traits< HalfedgeGraph >::null_face()) &&
527  (face(h2, _g) != boost::graph_traits< HalfedgeGraph >::null_face()))
528  {
529  halfedge_descriptor hnew =
530  CGAL::Euler::split_vertex< HalfedgeGraph >(h1, h2, _g);
531  CGAL::Euler::split_face(
532  prev(prev(opposite(hnew, _g), _g), _g), opposite(hnew, _g), _g);
533  CGAL::Euler::split_face(hnew, next(next(hnew, _g), _g), _g);
534 
535  return hnew;
536  }
537  return h1;
538  }
539 
540 
541  std::pair< halfedge_descriptor, bool > find_good_border(halfedge_descriptor h)
542  {
543  halfedge_descriptor hb = h;
544  bool ok = false;
545  do
546  {
547  hb = opposite(next(hb, _g), _g);
548  // check if good border or if it's a hole in the mesh
549  if(CGAL::is_border(hb, _g))
550  {
551  ok = true;
552  }
553  else
554  {
555 
556  if(CGAL::is_border(opposite(hb, _g), _g))
557  {
558  hb = opposite(hb, _g);
559  ok = true;
560  }
561  }
562  } while((hb != h) && !ok);
563 
564  return std::make_pair(hb, ok);
565  }
566 
567  std::pair< halfedge_descriptor, halfedge_descriptor >
569  {
570  halfedge_descriptor h1, h2;
571  if(cas == TOPOLOGY_CASE::CASE11)
572  {
573  // case 1
574  h2 = h;
575  // find good border
576  std::pair< halfedge_descriptor, bool > paire = this->find_good_border(h2);
577  if(paire.second == false)
578  {
579  FEVV::PMapsContainer test_pmaps_bag;
580  color_vertex(
581  _g,
582  _pm,
583  _vcm,
584  target(h2, _g),
585  typename boost::property_traits< VertexColorMap >::value_type(
586  1, 0, 0));
587  put_property_map(FEVV::vertex_color, _g, test_pmaps_bag, _vcm);
588  FEVV::Filters::write_mesh("test11.obj", _g, test_pmaps_bag);
589  std::cerr << "find_good_halfedges_for_split: error, there is no good border found " << std::endl;
590  assert(false);
591  }
592  else
593  h1 = paire.first;
594  }
595 
596  else if(cas == TOPOLOGY_CASE::CASE12)
597  {
598  // case 2
599  h2 = h;
600  // find good border
601  std::pair< halfedge_descriptor, bool > paire = this->find_good_border(h2);
602  if(paire.second == false)
603  {
604  FEVV::PMapsContainer test_pmaps_bag;
605  color_vertex(
606  _g,
607  _pm,
608  _vcm,
609  target(h2, _g),
610  typename boost::property_traits< VertexColorMap >::value_type(
611  1, 0, 0));
612  put_property_map(FEVV::vertex_color, _g, test_pmaps_bag, _vcm);
613  FEVV::Filters::write_mesh("test12.obj", _g, test_pmaps_bag);
614  std::cerr << "find_good_halfedges_for_split: error, there is no good border found " << std::endl;
615  assert(false);
616  }
617  else
618  h1 = paire.first;
619  }
620 
621  else if(cas == TOPOLOGY_CASE::CASE13)
622  {
623  // case 3
624  h2 = prev(opposite(h, _g), _g);
625  // find good border
626  std::pair< halfedge_descriptor, bool > paire = this->find_good_border(h2);
627  if(paire.second == false)
628  {
629  FEVV::PMapsContainer test_pmaps_bag;
630  color_vertex(
631  _g,
632  _pm,
633  _vcm,
634  target(h, _g),
635  typename boost::property_traits< VertexColorMap >::value_type(
636  1, 0, 0));
637  color_vertex(
638  _g,
639  _pm,
640  _vcm,
641  target(h2, _g),
642  typename boost::property_traits< VertexColorMap >::value_type(
643  1, 1, 0));
644  put_property_map(FEVV::vertex_color, _g, test_pmaps_bag, _vcm);
645  FEVV::Filters::write_mesh("test13.obj", _g, test_pmaps_bag);
646  std::cerr << "find_good_halfedges_for_split: error, there is no good border found " << std::endl;
647  assert(false);
648  }
649  else
650  h1 = paire.first;
651  }
652 
653  else
654  {
655  std::cerr << "find_good_halfedges_for_split: error , wrong case " << std::endl;
656  assert(false);
657  }
658 
659  return std::make_pair(h1, h2);
660  }
661 
662 
664  {
665 
666  face_descriptor f = face(h, _g);
667  if(f == boost::graph_traits< HalfedgeGraph >::null_face())
668  {
669  std::cerr << "get_face_degree: null face " << std::endl;
670  return 0;
671  }
672  else
673  {
674  boost::iterator_range<
675  CGAL::Vertex_around_face_iterator< HalfedgeGraph > >
676  iterator_range_v = CGAL::vertices_around_face(h, _g);
677  int nb_face_vertices = 0;
678 
679 #ifdef __GNUC__
680 #pragma GCC diagnostic push
681 #pragma GCC diagnostic ignored "-Wunused-but-set-variable"
682 #endif //__GNUC__
683  for(auto v : iterator_range_v)
684  {
685  nb_face_vertices += 1;
686  }
687 #ifdef __GNUC__
688 #pragma GCC diagnostic pop
689 #endif //__GNUC__
690 
691  if(nb_face_vertices == 1 || nb_face_vertices == 2)
692  {
693  std::cerr << "get_face_degree: error, there are not enough vertices to make a face "
694  << std::endl;
695  assert(false);
696  return 0;
697  }
698  else
699  return nb_face_vertices;
700  }
701  }
703  {
704  halfedge_descriptor hnew, h1, h2;
705  std::pair< halfedge_descriptor, halfedge_descriptor > pair_of_h;
706  switch(current_case)
707  {
708  case FEVV::Filters::TOPOLOGY_CASE::CASE11:
709  pair_of_h = find_good_halfedges_for_split(h, current_case);
710  h1 = pair_of_h.first;
711  h2 = pair_of_h.second;
712 
713  hnew = CGAL::Euler::split_vertex(h1, h2, _g);
714  if(this->get_face_degree(hnew) == 4)
715  CGAL::Euler::split_face(hnew, next(next(hnew, _g), _g), _g);
716  break;
717 
718  case FEVV::Filters::TOPOLOGY_CASE::CASE12:
719  pair_of_h = find_good_halfedges_for_split(h, current_case);
720  h1 = pair_of_h.first;
721  h2 = pair_of_h.second;
722  hnew = CGAL::Euler::split_vertex(h1, h2, _g);
723 
724  CGAL::internal::set_border(opposite(hnew, _g), _g);
725 
726  CGAL::Euler::split_face(hnew, next(next(hnew, _g), _g), _g);
727  break;
728 
729  case FEVV::Filters::TOPOLOGY_CASE::CASE13:
730 
731  pair_of_h = find_good_halfedges_for_split(h, current_case);
732  h1 = pair_of_h.first;
733  h2 = pair_of_h.second;
734  if(h1 != h2)
735  {
736 
737  hnew = CGAL::Euler::split_vertex(h1, h2, _g);
738 
739  CGAL::internal::set_border(opposite(hnew, _g), _g);
740 
741  CGAL::Euler::split_face(prev(hnew, _g), next(hnew, _g), _g);
742  }
743  else
744  {
745  color_vertex(
746  _g,
747  _pm,
748  _vcm,
749  target(h, _g),
750  typename boost::property_traits< VertexColorMap >::value_type(
751  1, 0, 0));
752  hnew = h;
753  }
754 
755  break;
756 
757  default:
758  break;
759  }
760 
761  return hnew;
762  }
763 
764 
767  TOPOLOGY_CASE current_case)
768  {
769  halfedge_descriptor first_to_split, second_to_split, border;
770  vertex_descriptor first, second, third;
771  std::vector< vertex_descriptor > face_vertices;
772  face_vertices.reserve(3);
773  halfedge_descriptor hnew = CGAL::Euler::split_vertex(h1, h2, _g);
774  switch(current_case)
775  {
776 
777  case FEVV::Filters::TOPOLOGY_CASE::CASE211:
778  first_to_split = hnew;
779  second_to_split = prev(prev(hnew, _g), _g);
780  border = opposite(hnew, _g);
781  first = source(hnew, _g);
782  second = source(h1, _g);
783  third = target(hnew, _g);
784  break;
785  case FEVV::Filters::TOPOLOGY_CASE::CASE221:
786  first_to_split = hnew;
787  second_to_split = prev(prev(hnew, _g), _g);
788  border = opposite(hnew, _g);
789  first = source(hnew, _g);
790  second = source(h1, _g);
791  third = target(hnew, _g);
792 
793  break;
794 
795  case FEVV::Filters::TOPOLOGY_CASE::CASE212:
796  first_to_split = opposite(hnew, _g);
797  second_to_split = prev(prev(opposite(hnew, _g), _g), _g);
798  border = hnew;
799  first = target(hnew, _g);
800  second = source(h2, _g);
801  third = source(hnew, _g);
802  break;
803  case FEVV::Filters::TOPOLOGY_CASE::CASE222:
804  first_to_split = opposite(hnew, _g);
805  second_to_split = prev(prev(opposite(hnew, _g), _g), _g);
806  border = hnew;
807  first = target(hnew, _g);
808  second = source(h2, _g);
809  third = source(hnew, _g);
810  break;
811  default:
812  break;
813  }
814  CGAL::Euler::split_face(first_to_split, second_to_split, _g);
815  // CGAL::internal::set_border(border, _g);
816  face_vertices.push_back(first);
817  face_vertices.push_back(second);
818  face_vertices.push_back(third);
819  CGAL::Euler::add_face(face_vertices, _g);
820  return hnew;
821  }
822 };
823 } // namespace Filters
824 } // namespace FEVV
CGAL::Euler::add_face
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor add_face(const VertexRange &vr, FEVV::DataStructures::AIF::AIFMesh &g)
Definition: Graph_traits_aif.h:1104
FEVV::Filters::Batch_decompressor::_edge_bitmask
std::list< bool > _edge_bitmask
Definition: Batch_decompressor.h:271
FEVV::Filters::Batch_decompressor::cases_2
halfedge_descriptor cases_2(halfedge_descriptor h1, halfedge_descriptor h2, TOPOLOGY_CASE current_case)
Definition: Batch_decompressor.h:765
FEVV::Filters::Batch_decompressor::decompress_binary_batch
void decompress_binary_batch(draco::DecoderBuffer &buffer)
Decompresses a batch using a draco buffer. This function implements lines 5 to 19 of Algorithm 2.
Definition: Batch_decompressor.h:207
FEVV::put_property_map
void put_property_map(PropertyT p, const MeshT &, PMapsContainer &pmaps, const typename PMap_traits< PropertyT, MeshT >::pmap_type &pmap)
Definition: properties.h:664
FEVV::Header_handler::get_init_coord
const std::vector< double > & get_init_coord() const
Definition: Header_handler.h:161
FEVV::Filters::Batch_decompressor::Point
typename FEVV::Geometry_traits< HalfedgeGraph >::Point Point
Definition: Batch_decompressor.h:89
Coarse_mesh_decoder.h
FEVV::DataStructures::AIF::next
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor next(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the next halfedge around its face.
Definition: Graph_traits_aif.h:599
FEVV::Filters::Batch_decompressor::_g
HalfedgeGraph & _g
Definition: Batch_decompressor.h:255
DataStructures_cgal_linear_cell_complex.h
FEVV::Filters::Batch_decompressor::find_good_border
std::pair< halfedge_descriptor, bool > find_good_border(halfedge_descriptor h)
Definition: Batch_decompressor.h:541
FEVV::Filters::Batch_decompressor::find_case
FEVV::Filters::TOPOLOGY_CASE find_case(halfedge_descriptor h1, halfedge_descriptor h2)
Definition: Batch_decompressor.h:455
FEVV::Filters::Batch_decompressor::Vector
typename FEVV::Geometry_traits< HalfedgeGraph >::Vector Vector
Definition: Batch_decompressor.h:88
Volume_preserving.h
FEVV::Comparator::get_adjacent_vertices
std::list< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor > get_adjacent_vertices(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &)
Definition: Spanning_tree_vertex_edge_comparator.hpp:28
FEVV::Filters::Batch_decompressor::predict_positions
void predict_positions(const std::list< halfedge_descriptor > &h_extent, std::list< std::pair< Point, Point > > &new_points)
predict_positions: Given a list of halfedges, will predict every pair of vertices of a split....
Definition: Batch_decompressor.h:130
FEVV::Filters::Batch_decompressor::find_good_halfedges_for_split
std::pair< halfedge_descriptor, halfedge_descriptor > find_good_halfedges_for_split(halfedge_descriptor h, TOPOLOGY_CASE cas)
Definition: Batch_decompressor.h:568
FEVV::Header_handler::get_quantization
int get_quantization() const
Definition: Header_handler.h:159
FEVV::Filters::Batch_decompressor::_vcm
VertexColorMap & _vcm
Definition: Batch_decompressor.h:275
FEVV::Comparator
Definition: Spanning_tree_vertex_edge_comparator.hpp:25
FEVV::Header_handler::get_dimension
const std::vector< double > & get_dimension() const
Definition: Header_handler.h:160
properties_linear_cell_complex.h
FEVV::Filters::Batch_decompressor::Batch_decompressor
Batch_decompressor(HalfedgeGraph &g, PointMap &pm, Predictor< HalfedgeGraph, PointMap > *predictor, FEVV::Filters::Kept_position< HalfedgeGraph, PointMap, Geometry > *vkept, const FEVV::Header_handler &header, VertexColorMap &vcm)
Batch_decompressor.
Definition: Batch_decompressor.h:106
FEVV::Filters::Batch_decompressor::save_spanning_tree
void save_spanning_tree(const FEVV::Comparator::Spanning_tree_vertex_edge_comparator< HalfedgeGraph, PointMap > &spanningtree)
saves spanning tree (useful for debugging)
Definition: Batch_decompressor.h:164
FEVV::Filters::Batch_decompressor::Geometry
typename FEVV::Geometry_traits< HalfedgeGraph > Geometry
Definition: Batch_decompressor.h:90
FEVV::DataStructures::AIF::opposite
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor opposite(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the halfedge with source and target swapped.
Definition: Graph_traits_aif.h:625
FEVV::Geometry_traits
Refer to Geometry_traits_documentation_dummy for further documentation on provided types and algorith...
Definition: Geometry_traits.h:162
Uniform_dequantization.h
Binary_batch_decoder.h
FEVV::Filters::Uniform_dequantization::point_dequantization
void point_dequantization()
Dequantizes all vertex positions stored in the point map.
Definition: Uniform_dequantization.h:111
FEVV::Filters::Binary_batch_decoder
Definition: Binary_batch_decoder.h:41
FEVV::DataStructures::AIF::source
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor source(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the source vertex of e.
Definition: Graph_traits_aif.h:387
FEVV::PMapsContainer
std::map< std::string, boost::any > PMapsContainer
Definition: properties.h:99
Memory_comparator.h
FEVV::Filters::Predictor
Abstract class used to predict position.
Definition: Predictor.h:35
FEVV::Filters::Batch_decompressor::_vkept
FEVV::Filters::Kept_position< HalfedgeGraph, PointMap, Geometry > * _vkept
Definition: Batch_decompressor.h:266
FEVV::Filters::Batch_decompressor::halfedge_descriptor
typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor halfedge_descriptor
Definition: Batch_decompressor.h:85
FEVV::Filters::Batch_decompressor::fill_h_extent_list_no_sort
void fill_h_extent_list_no_sort(const FEVV::Comparator::Spanning_tree_vertex_edge_comparator< HalfedgeGraph, PointMap, Geometry > &spanningtree, std::list< halfedge_descriptor > &h_extent)
Definition: Batch_decompressor.h:352
FEVV::get
FEVV::PCLPointCloudPointMap::value_type get(const FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key)
Specialization of get(point_map, key) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:117
FEVV::Comparator::Spanning_tree_vertex_edge_comparator
Definition: Spanning_tree_vertex_edge_comparator.hpp:258
FEVV::Filters::Kept_position
Abstract class to represent the position type of the resulting vertex of an edge collapse.
Definition: Kept_position.h:31
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Filters::Batch_decompressor::dequantize_mesh
void dequantize_mesh()
Dequantizes a mesh (restores integers as original doubles)
Definition: Batch_decompressor.h:188
FEVV::Filters::Batch_decompressor::~Batch_decompressor
~Batch_decompressor()
Definition: Batch_decompressor.h:120
Butterfly.h
FEVV::DataStructures::AIF::halfedge
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor halfedge(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns a halfedge with target v.
Definition: Graph_traits_aif.h:296
FEVV::DataStructures::AIF::target
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor target(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor e, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the target vertex of e.
Definition: Graph_traits_aif.h:400
FEVV::Filters::TOPOLOGY_CASE::CASE11
@ CASE11
apply_color.h
FEVV::vertex_color
@ vertex_color
Definition: properties.h:47
FEVV::Filters::Batch_decompressor::_pm
PointMap & _pm
Definition: Batch_decompressor.h:256
FEVV::Filters::Batch_decompressor::cases_1
halfedge_descriptor cases_1(halfedge_descriptor h, TOPOLOGY_CASE current_case)
Definition: Batch_decompressor.h:702
FEVV::Filters::Batch_decompressor::simple_split_sase
halfedge_descriptor simple_split_sase(halfedge_descriptor h1, halfedge_descriptor h2)
Definition: Batch_decompressor.h:521
FEVV::Filters::Batch_decompressor::_bitmask
std::list< bool > _bitmask
Definition: Batch_decompressor.h:270
Edge_length_metric.h
FEVV::Filters::Batch_decompressor::_gt
const Geometry _gt
Definition: Batch_decompressor.h:257
FEVV::DataStructures::AIF::prev
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor prev(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the previous halfedge around its face.
Definition: Graph_traits_aif.h:612
FEVV::Filters::Uniform_dequantization< HalfedgeGraph, PointMap >
FEVV::Filters::write_mesh
void write_mesh(const std::string &filename, FEVV::CGALPointSet &g, PMapsContainer &pmaps)
Write mesh to file.
Definition: cgal_point_set_writer.hpp:42
generic_writer.hpp
FEVV::Filters::Batch_decompressor::vertex_descriptor
typename boost::graph_traits< HalfedgeGraph >::vertex_descriptor vertex_descriptor
Definition: Batch_decompressor.h:83
FEVV::Filters::Batch_decompressor
Batch_decompressor: Given a draco buffer, will decompress a non-textured (or not) mesh.
Definition: Batch_decompressor.h:78
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
Geometric_metrics.h
FEVV::Filters::Batch_decompressor::_other_info_bits
std::list< bool > _other_info_bits
Definition: Batch_decompressor.h:272
FEVV::put
void put(FEVV::PCLPointCloudPointMap &pm, FEVV::PCLPointCloudPointMap::key_type key, const FEVV::PCLPointCloudPointMap::value_type &value)
Specialization of put(point_map, key, value) for PCLPointCloud.
Definition: Graph_properties_pcl_point_cloud.h:126
FEVV::DataStructures::AIF::face
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_descriptor face(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::halfedge_descriptor h, const FEVV::DataStructures::AIF::AIFMesh &)
Returns the face incident to halfedge h.
Definition: Graph_traits_aif.h:664
FEVV::Header_handler
Definition: Header_handler.h:35
FEVV::Filters::Batch_decompressor::_predictor
FEVV::Filters::Predictor< HalfedgeGraph, PointMap > * _predictor
Definition: Batch_decompressor.h:263
FEVV::Filters::Batch_decompressor::neighbours_bitmasks
std::vector< std::vector< bool > > neighbours_bitmasks
Definition: Batch_decompressor.h:258
Spanning_tree_vertex_edge_comparator.hpp
FEVV::Filters::Batch_decompressor::split_vertices
bool split_vertices(const std::list< halfedge_descriptor > &h_extent)
This function implements lines 13 to 19 of Algorithm 2.
Definition: Batch_decompressor.h:278
FEVV::Comparator::get_not_processed_adjacent_vertices
std::list< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor > get_not_processed_adjacent_vertices(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor v, const FEVV::DataStructures::AIF::AIFMesh &g, std::map< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor, bool > &processed_vertices, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::edge_descriptor min_e)
Definition: Spanning_tree_vertex_edge_comparator.hpp:38
FEVV::Filters::Batch_decompressor::get_face_degree
int get_face_degree(halfedge_descriptor h)
Definition: Batch_decompressor.h:663
FEVV::Filters::Batch_decompressor::_positions
std::list< std::vector< Vector > > _positions
Definition: Batch_decompressor.h:268
Raw_positions.h
Header_handler.h
FEVV::Filters::TOPOLOGY_CASE
TOPOLOGY_CASE
Definition: Batch_decompressor.h:56
FEVV::Filters::Batch_decompressor::_batch_id
int _batch_id
Definition: Batch_decompressor.h:259
FEVV::Filters::color_vertex
void color_vertex(HalfedgeGraph &, PointMap &, VertexColorMap &v_cm, vertex_descriptor vertex_to_color, typename boost::property_traits< VertexColorMap >::value_type color)
Colors a vertex by putting the specified color into the vertex color map at the "vertex" position....
Definition: apply_color.h:56
Geometry_traits_cgal_linear_cell_complex.h
FEVV::Filters::Batch_decompressor::face_descriptor
typename boost::graph_traits< HalfedgeGraph >::face_descriptor face_descriptor
Definition: Batch_decompressor.h:87
FEVV::Filters::Batch_decompressor::_header
const FEVV::Header_handler & _header
Definition: Batch_decompressor.h:273