MEPP2 Project
color_mesh.h
Go to the documentation of this file.
1 // Copyright (c) 2012-2019 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 #pragma once
12 
13 #include <CGAL/boost/graph/properties.h>
14 #include <boost/foreach.hpp>
15 #include <limits>
16 #include <stdexcept> // for std::invalid_argument
17 #include <cmath> // for std::fmod
18 #include <vector>
19 
20 namespace FEVV {
21 namespace Filters {
22 
23 // Numeric maps
24 
25 typedef std::vector< float > ColorMeshLUT;
26 
39 inline
41 make_LUT(bool color_in_0_255 = true,
42  unsigned int colors_nbr = 256,
43  float h1 = 240,
44  float h2 = 0)
45 {
46  // check parameters
47  if(h1 == h2)
48  throw std::invalid_argument("make_LUT: h1 and h2 must be different.");
49  if(colors_nbr == 0)
50  throw std::invalid_argument("make_LUT: colors_nbr must not be zero.");
51 
52  // create LUT
53  ColorMeshLUT rgb_LUT(3*colors_nbr);
54 
55  // initializations
56  float max_color_value = 1;
57  if(color_in_0_255)
58  max_color_value = 255;
59  float step = (h2 - h1)/colors_nbr;
60  float H = h1;
61  const float S = 1;
62  const float V = 1;
63 
64  // helper lambda function to convert HSV to RGB
65  // see https://en.wikipedia.org/wiki/HSL_and_HSV#HSV_to_RGB
66  // section "HSV to RGB alternative"
67  auto f = [](float h, float s, float v, int n) -> float
68  {
69  float k = std::fmod(n + h/60.0f, 6.0f);
70  return v - v*s*std::max(std::min({k, 4-k, 1.0f}), 0.0f);
71  };
72 
73  // populate LUT
74  for(unsigned int i = 0; i < colors_nbr; i++)
75  {
76 
77  rgb_LUT[3 * i] = max_color_value * f(H, S, V, 5); // R
78  rgb_LUT[3 * i + 1] = max_color_value * f(H, S, V, 3); // G
79  rgb_LUT[3 * i + 2] = max_color_value * f(H, S, V, 1); // B
80 
81  H += step;
82  }
83 
84  return rgb_LUT;
85 }
86 
87 
100 template< typename Descriptor,
101  typename PropertyMap,
102  typename ColorMap,
103  typename MapType = typename PropertyMap::value_type >
104 void
105 color_descriptor_from_map(const Descriptor &d,
106  const PropertyMap &prop_map,
107  ColorMap &color_pmap,
108  const MapType min_metric,
109  const MapType max_metric,
110  const ColorMeshLUT &colors)
111 {
112  typedef typename boost::property_traits< ColorMap >::value_type Color;
113  // this is a work-around to retrieve the color component type (aka float
114  // with meshes and uchar with point clouds)
115  Color dummy;
116  typedef typename std::remove_reference< decltype(dummy[0]) >::type
117  ColorComponent;
118  // note: std::remove_reference< > is needed because dummy[0] is a reference
119  // with some datastructure (PCL).
120  // TODO-elo: fix this work-around by something like
121  // typedef color_traits< Color >::component_type ColorComponent
122  // when a 'Color traits' is implemented
123 
124  size_t number_of_colors = colors.size() / 3;
125 
126  if(min_metric != max_metric)
127  {
128  // retrieve value from property map
129  MapType val_metric = get(prop_map, d);
130 
131  // ensure value is between min and max to avoid LUT overflow
132  val_metric = std::min(val_metric, max_metric);
133  val_metric = std::max(val_metric, min_metric);
134 
135  // convert value to LUT id
136  MapType id = (val_metric - min_metric) / (max_metric - min_metric);
137  int indice_lut = static_cast< int >(std::floor((number_of_colors - 1) * id));
138 
139  // convert value to color
140  Color newcolor(static_cast< ColorComponent >(colors[3 * indice_lut]),
141  static_cast< ColorComponent >(colors[3 * indice_lut + 1]),
142  static_cast< ColorComponent >(colors[3 * indice_lut + 2]));
143  put(color_pmap, d, newcolor);
144  }
145  else
146  {
147  // use first color of the color map for all values
148  put(color_pmap, d, Color(static_cast< ColorComponent >(colors[0]),
149  static_cast< ColorComponent >(colors[1]),
150  static_cast< ColorComponent >(colors[2])));
151  }
152 }
153 
154 
167 template< typename HalfedgeGraph,
168  typename PropertyMap,
169  typename ColorMap,
170  typename MapType = typename PropertyMap::value_type >
171 void
172 color_faces_from_map(const HalfedgeGraph &g,
173  const PropertyMap &prop_map,
174  ColorMap &color_pmap,
175  const MapType min_metric,
176  const MapType max_metric,
177  const ColorMeshLUT &colors = make_LUT())
178 {
179  typedef typename boost::graph_traits< HalfedgeGraph >::face_descriptor
180  Face_Descriptor;
181 
182  BOOST_FOREACH(Face_Descriptor f, faces(g))
183  {
185  prop_map,
186  color_pmap,
187  min_metric,
188  max_metric,
189  colors);
190  }
191 }
192 
193 
206 template< typename HalfedgeGraph,
207  typename PropertyMap,
208  typename ColorMap,
209  typename MapType = typename PropertyMap::value_type >
210 void
211 color_vertices_from_map(const HalfedgeGraph &g,
212  const PropertyMap &prop_map,
213  ColorMap &color_pmap,
214  const MapType min_metric,
215  const MapType max_metric,
216  const ColorMeshLUT &colors = make_LUT())
217 {
220 
221  BOOST_FOREACH(Vertex_Descriptor v, vertices(g))
222  {
224  prop_map,
225  color_pmap,
226  min_metric,
227  max_metric,
228  colors);
229  }
230 }
231 
232 
245 template< typename HalfedgeGraph,
246  typename PropertyMap,
247  typename ColorMap,
248  typename MapType = typename PropertyMap::value_type >
249 void
250 color_halfedges_from_map(const HalfedgeGraph &g,
251  const PropertyMap &prop_map,
252  ColorMap &color_pmap,
253  const MapType min_metric,
254  const MapType max_metric,
255  const ColorMeshLUT &colors = make_LUT())
256 {
257  typedef typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor
258  Halfedge_Descriptor;
259 
260  BOOST_FOREACH(Halfedge_Descriptor h, halfedges(g))
261  {
263  prop_map,
264  color_pmap,
265  min_metric,
266  max_metric,
267  colors);
268  }
269 }
270 
271 // Boolean map
272 
284 template<
285  typename Descriptor,
286  typename BooleanMap,
287  typename ColorMap,
288  typename Color = typename boost::property_traits< ColorMap >::value_type >
289 void
290 color_descriptor_from_bool(const Descriptor &d,
291  const BooleanMap &prop_map,
292  ColorMap &color_pmap,
293  const Color &color1,
294  const Color &color2)
295 {
296  if(get(prop_map, d))
297  {
298  put(color_pmap, d, color1);
299  }
300  else
301  {
302  put(color_pmap, d, color2);
303  }
304 }
305 
306 
318 template<
319  typename HalfedgeGraph,
320  typename BooleanMap,
321  typename ColorMap,
322  typename Color = typename boost::property_traits< ColorMap >::value_type >
323 void
324 color_faces_from_bool_map(const HalfedgeGraph &g,
325  const BooleanMap &prop_map,
326  ColorMap &color_pmap,
327  const Color &color1,
328  const Color &color2)
329 {
330  typedef typename boost::graph_traits< HalfedgeGraph >::face_descriptor
331  Face_Descriptor;
332 
333  BOOST_FOREACH(Face_Descriptor f, faces(g))
334  {
335  color_descriptor_from_bool(f, prop_map, color_pmap, color1, color2);
336  }
337 }
338 
350 template<
351  typename HalfedgeGraph,
352  typename BooleanMap,
353  typename ColorMap,
354  typename Color = typename boost::property_traits< ColorMap >::value_type >
355 void
356 color_vertices_from_bool_map(const HalfedgeGraph &g,
357  const BooleanMap &prop_map,
358  ColorMap &color_pmap,
359  const Color &color1,
360  const Color &color2)
361 {
364 
365  BOOST_FOREACH(Vertex_Descriptor v, vertices(g))
366  {
367  color_descriptor_from_bool(v, prop_map, color_pmap, color1, color2);
368  }
369 }
370 
382 template<
383  typename HalfedgeGraph,
384  typename BooleanMap,
385  typename ColorMap,
386  typename Color = typename boost::property_traits< ColorMap >::value_type >
387 void
388 color_halfedge_from_bool_map(const HalfedgeGraph &g,
389  const BooleanMap &prop_map,
390  ColorMap &color_pmap,
391  const Color &color1,
392  const Color &color2)
393 {
394  typedef typename boost::graph_traits< HalfedgeGraph >::halfedge_descriptor
395  Halfedge_Descriptor;
396 
397  BOOST_FOREACH(Halfedge_Descriptor h, halfedges(g))
398  {
399  color_descriptor_from_bool(h, prop_map, color_pmap, color1, color2);
400  }
401 }
402 } // namespace Filters
403 } // namespace FEVV
FEVV::DataStructures::AIF::vertices
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::vertex_iterator > vertices(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns the iterator range of the vertices of the mesh.
Definition: Graph_traits_aif.h:172
FEVV::Filters::color_halfedges_from_map
void color_halfedges_from_map(const HalfedgeGraph &g, const PropertyMap &prop_map, ColorMap &color_pmap, const MapType min_metric, const MapType max_metric, const ColorMeshLUT &colors=make_LUT())
Fill the color map for the halfedges of a mesh using a numerical property map.
Definition: color_mesh.h:250
FEVV::Vertex_Descriptor
MeshSurface::Vertex_index Vertex_Descriptor
Definition: cmdm.h:44
FEVV::Filters::color_vertices_from_map
void color_vertices_from_map(const HalfedgeGraph &g, const PropertyMap &prop_map, ColorMap &color_pmap, const MapType min_metric, const MapType max_metric, const ColorMeshLUT &colors=make_LUT())
Fill the color map for the vertices of a mesh using a numerical property map.
Definition: color_mesh.h:211
FEVV::Filters::make_LUT
ColorMeshLUT make_LUT(bool color_in_0_255=true, unsigned int colors_nbr=256, float h1=240, float h2=0)
Create a RGB LUT based on an HSV range. Default range creates a blue-cyan-green-yellow-red gradient.
Definition: color_mesh.h:41
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
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::Filters::color_vertices_from_bool_map
void color_vertices_from_bool_map(const HalfedgeGraph &g, const BooleanMap &prop_map, ColorMap &color_pmap, const Color &color1, const Color &color2)
Fill the color map for the vertices of a mesh using a boolean property map.
Definition: color_mesh.h:356
FEVV::DataStructures::AIF::faces
std::pair< typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_iterator, typename boost::graph_traits< FEVV::DataStructures::AIF::AIFMesh >::face_iterator > faces(const FEVV::DataStructures::AIF::AIFMesh &sm)
Returns an iterator range over all faces of the mesh.
Definition: Graph_traits_aif.h:679
FEVV::Filters::color_halfedge_from_bool_map
void color_halfedge_from_bool_map(const HalfedgeGraph &g, const BooleanMap &prop_map, ColorMap &color_pmap, const Color &color1, const Color &color2)
Fill the color map for the halfedges of a mesh using a boolean property map.
Definition: color_mesh.h:388
FEVV::Filters::color_faces_from_map
void color_faces_from_map(const HalfedgeGraph &g, const PropertyMap &prop_map, ColorMap &color_pmap, const MapType min_metric, const MapType max_metric, const ColorMeshLUT &colors=make_LUT())
Fill the color map for the faces of a mesh using a numerical property map.
Definition: color_mesh.h:172
FEVV::Filters::ColorMeshLUT
std::vector< float > ColorMeshLUT
Definition: color_mesh.h:25
FEVV::Filters::color_descriptor_from_bool
void color_descriptor_from_bool(const Descriptor &d, const BooleanMap &prop_map, ColorMap &color_pmap, const Color &color1, const Color &color2)
Set the color for the descriptor using a boolean property map and the colors given.
Definition: color_mesh.h:290
FEVV::Color
Definition: Color.hpp:18
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::Filters::color_faces_from_bool_map
void color_faces_from_bool_map(const HalfedgeGraph &g, const BooleanMap &prop_map, ColorMap &color_pmap, const Color &color1, const Color &color2)
Fill the color map for the faces of a mesh using a boolean property map.
Definition: color_mesh.h:324
FEVV::Filters::color_descriptor_from_map
void color_descriptor_from_map(const Descriptor &d, const PropertyMap &prop_map, ColorMap &color_pmap, const MapType min_metric, const MapType max_metric, const ColorMeshLUT &colors)
Set the color for the descriptor using a numerical property map and the color array given.
Definition: color_mesh.h:105