MEPP2 Project
Coarse_mesh_decoder.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>
17 
18 #include <iostream>
19 #include <vector>
20 #include <map>
21 #include <utility>
22 
23 #ifdef _MSC_VER
24 #pragma warning(push)
25 #pragma warning(disable : 4146 26812 26451)
26 #endif
27 
29 
30 #if defined _MSC_VER
31 #pragma warning(pop)
32 #endif
33 
34 namespace FEVV {
35 namespace Filters {
36 template<
37  typename HalfedgeGraph,
38  typename PointMap,
39  typename vertex_descriptor =
41  typename halfedge_descriptor =
42  typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor >
44 {
45 public:
46  typedef typename boost::property_traits<PointMap>::value_type Point;
47 
51  Coarse_mesh_decoder(HalfedgeGraph &g,
52  PointMap &pm
53  ) : _g(g), _pm(pm) {}
54 
56 
59  void decode_coarse_mesh(draco::DecoderBuffer &buffer)
60  {
61  draco::Decoder decoder;
62  decoder.SetSkipAttributeTransform(
63  draco::GeometryAttribute::POSITION); // do not touch attributes
64  // quantization (already done)
65  std::unique_ptr< draco::PointCloud > pc;
66 
67  draco::Mesh *mesh = nullptr;
68  // if our mesh is a triangular mesh, decode it
69  auto type_statusor = decoder.GetEncodedGeometryType(&buffer);
70  if(!type_statusor.ok())
71  {
72  std::cerr << "decode_coarse_mesh: failed to retrieve geometry " << std::endl;
73  return;
74  }
75  const draco::EncodedGeometryType geom_type = type_statusor.value();
76  if(geom_type == draco::TRIANGULAR_MESH)
77  {
78  auto statusor = decoder.DecodeMeshFromBuffer(&buffer);
79  if(!statusor.ok())
80  {
81  std::cerr << "decode_coarse_mesh: failed to retrieve coarse mesh " << std::endl;
82  return;
83  }
84  std::unique_ptr< draco::Mesh > in_mesh = std::move(statusor).value();
85  if(in_mesh)
86  {
87  mesh = in_mesh.get();
88  pc = std::move(in_mesh);
89  }
90  }
91 
92  if(pc == nullptr){
93  std::cerr << "decode_coarse_mesh: Failed to decode the input file" << std::endl;
94  }
95  else
97  }
98 
100  {
101  const draco::PointCloud *p_point_cloud =
102  &(static_cast< const draco::PointCloud & >(mesh));
103  const draco::Mesh *p_mesh = &mesh;
104  // create a map that permits retriving a vertex from its index
105  std::map< int, vertex_descriptor > map_index_to_vertex;
106 
107  // Encode points position into a buffer and faces into an other buffer
108  const draco::PointAttribute *const att =
109  p_point_cloud->GetNamedAttribute(draco::GeometryAttribute::POSITION);
110  if(!get_mepp_mesh_vertex(p_point_cloud, att, &map_index_to_vertex))
111  return false;
112  if(!get_mepp_mesh_face(p_mesh, att, map_index_to_vertex))
113  return false;
114  return true;
115  }
116 
117  bool
118  get_mepp_mesh_vertex(const draco::PointCloud * /*p_point_cloud*/,
119  const draco::PointAttribute *const att,
120  std::map< int, vertex_descriptor > *map_index_to_vertex)
121  {
122  if(att == nullptr || att->size() == 0)
123  return false; // Position attribute must be valid.
124  std::array< float, 3 > value;
125  for(draco::AttributeValueIndex i(0);
126  i < static_cast< uint32_t >(att->size());
127  ++i)
128  {
129  if(!att->ConvertValue< float, 3 >(i, &value[0]))
130  return false;
131  // insert new vertex in the mesh
133  map_index_to_vertex->insert(
134  std::pair< int, vertex_descriptor >(i.value(), v));
135  // get vertex position
136  Point vertex_pos = Point(value[0], value[1], value[2]);
137  // insert vertex position in map pm
138  put(_pm, v, vertex_pos);
139  }
140  return true;
141  }
142 
143  bool
145  const draco::PointAttribute *const att,
146  const std::map< int, vertex_descriptor > &map_index_to_vertex)
147  {
148  for(draco::FaceIndex i(0); i < p_mesh->num_faces(); ++i)
149  {
150  std::vector< int > face;
151  face.reserve(3);
152  for(int j = 0; j < 3; ++j)
153  {
154  if(!get_face_corner(i, j, p_mesh, face, att))
155  return false;
156  }
157 
158  // update mesh connectivity
159  set_mesh_connectivity_from_face(face, map_index_to_vertex);
160  }
161  return true;
162  }
163 
164  bool get_face_corner(draco::FaceIndex face_id,
165  int local_corner_id,
166  const draco::Mesh *p_mesh,
167  std::vector< int >& face,
168  const draco::PointAttribute *const att)
169  {
170  const draco::PointIndex vert_index = p_mesh->face(face_id)[local_corner_id];
171  // get vertices that makes the face
172  face.push_back(att->mapped_index(vert_index).value());
173  return true;
174  }
175 
176 
178  const std::vector< int >& face,
179  const std::map< int, vertex_descriptor > &map_index_to_vertex)
180  {
181  // make a vertex range from the face vertices
182  std::vector< vertex_descriptor > vertexRange;
183  vertexRange.reserve(3);
184  for(int i = 0; i < 3; i++)
185  {
186  vertex_descriptor v = map_index_to_vertex.find(face[i])->second;
187  vertexRange.push_back(v);
188  }
189 
190  // add face
191  CGAL::Euler::add_face< HalfedgeGraph, std::vector< vertex_descriptor > >(
192  vertexRange, _g);
193  }
194 
195 private:
196  HalfedgeGraph &_g; // HalfedgeGraph: at the beginning, will be empty. the
197  // function decode_coarse_mesh will add the vertices and
198  // corresponding connectivity from a draco buffer
199  PointMap &_pm; // Empty point map at the beginning. It will be filled thanks
200  // to the same draco buffer as _g
201 };
202 
203 } // namespace Filters
204 } // namespace FEVV
FEVV::Filters::Coarse_mesh_decoder::Coarse_mesh_decoder
Coarse_mesh_decoder(HalfedgeGraph &g, PointMap &pm)
Definition: Coarse_mesh_decoder.h:51
FEVV::Filters::Coarse_mesh_decoder::get_face_corner
bool get_face_corner(draco::FaceIndex face_id, int local_corner_id, const draco::Mesh *p_mesh, std::vector< int > &face, const draco::PointAttribute *const att)
Definition: Coarse_mesh_decoder.h:164
FEVV::Filters::Coarse_mesh_decoder::_pm
PointMap & _pm
Definition: Coarse_mesh_decoder.h:199
Coarse_mesh_decoder_draco_nowarning.h
FEVV::Filters::Coarse_mesh_decoder::get_mepp_mesh_face
bool get_mepp_mesh_face(const draco::Mesh *p_mesh, const draco::PointAttribute *const att, const std::map< int, vertex_descriptor > &map_index_to_vertex)
Definition: Coarse_mesh_decoder.h:144
FEVV::Filters::Coarse_mesh_decoder::decode_coarse_mesh
void decode_coarse_mesh(draco::DecoderBuffer &buffer)
Definition: Coarse_mesh_decoder.h:59
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Filters::Coarse_mesh_decoder::set_mesh_connectivity_from_face
void set_mesh_connectivity_from_face(const std::vector< int > &face, const std::map< int, vertex_descriptor > &map_index_to_vertex)
Definition: Coarse_mesh_decoder.h:177
FEVV::Filters::Coarse_mesh_decoder::~Coarse_mesh_decoder
~Coarse_mesh_decoder()
Definition: Coarse_mesh_decoder.h:55
FEVV::Filters::Coarse_mesh_decoder::Point
boost::property_traits< PointMap >::value_type Point
Definition: Coarse_mesh_decoder.h:46
Geometry_traits.h
FEVV::DataStructures::AIF::add_vertex
boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_descriptor add_vertex(typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_property_type vp, FEVV::DataStructures::AIF::AIFMesh &sm)
Definition: Graph_properties_aif.h:263
Mesh
FEVV::DataStructures::AIF::AIFMesh Mesh
Definition: test_complying_concepts_aif.cpp:18
FEVV::Filters::Coarse_mesh_decoder
Definition: Coarse_mesh_decoder.h:44
FEVV::Filters::Coarse_mesh_decoder::get_mesh_from_binary_file
bool get_mesh_from_binary_file(draco::Mesh &mesh)
Definition: Coarse_mesh_decoder.h:99
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
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::Filters::Coarse_mesh_decoder::get_mepp_mesh_vertex
bool get_mepp_mesh_vertex(const draco::PointCloud *, const draco::PointAttribute *const att, std::map< int, vertex_descriptor > *map_index_to_vertex)
Definition: Coarse_mesh_decoder.h:118
FEVV::Filters::Coarse_mesh_decoder::_g
HalfedgeGraph & _g
Definition: Coarse_mesh_decoder.h:196