MEPP2 Project
JndPlugin.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 General Public License as published
6 // by the Free Software Foundation; either version 3 of the License,
7 // 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 #if(_MSC_VER >= 1400)
14 #ifndef _SCL_SECURE_NO_WARNINGS
15 #define _SCL_SECURE_NO_WARNINGS
16 #endif
17 #endif
18 
20 
21 #include <QStringList>
22 #include "Dialogs/DialogJnd1.h"
23 
24 #ifndef Q_MOC_RUN // MT : very important to avoid the error : ' Parse error at
25  // "BOOST_JOIN" ' -> (qt4 pb with boost)
26 #include <sstream>
27 #include <string>
28 #include <boost/foreach.hpp>
29 #include <time.h>
30 #include <cmath>
31 
34 
36 
37 #include "FEVV/Filters/Generic/Manifold/JustNoticeableDistortion/just_noticeable_distortion.hpp" // A) include the header of the filter corresponding to your operation
38 
39 
41 #ifdef FEVV_USE_CGAL
45 #endif // FEVV_USE_CGAL
46 #ifdef FEVV_USE_OPENMESH
48 #endif // FEVV_USE_OPENMESH
49 #ifdef FEVV_USE_AIF
51 #endif // FEVV_USE_AIF
52 #endif // Q_MOC_RUN
53 
54 namespace FEVV {
55 
56 class JndPlugin : public QObject,
58  public BasePluginQt
59 {
60  Q_OBJECT
61  Q_INTERFACES(FEVV::Generic_PluginInterface)
62 #if(FEVV_USE_QT5) // see at the end of .cpp for QT4
63  Q_PLUGIN_METADATA(IID "JndPlugin")
64 #endif
65 
66  /*public:
67  using BasePlugin::apply;*/
68 public:
69  JndPlugin() = default;
70  ~JndPlugin() = default;
71 
72 public:
73  void init() override
74  {
75  *screen_width = 1920;
76  *screen_height = 1080;
77  *screen_size = 55.;
78  *user_dist = 50.;
79  *scene_height = 1080;
80  *scene_fov = M_PI * 0.3333;
81  *number_of_lights = 128;
82  *use_log = true;
83  }
84 
85 
86  void reset() override
87  {
88  init();
89 
90  emit resetSignal();
91  }
92 
93  void addParameters(BaseWindow *_window) override
94  {
95  window = _window;
96  if(window == nullptr || !window->isInit())
97  {
98  std::cerr << "BaseWindow is null or not initialized." << std::endl;
99  return;
100  }
101  }
102 
103  template< typename HalfedgeGraph >
104  void process(HalfedgeGraph *_m, FEVV::PMapsContainer *pmaps_bag)
105  {
106 
107  typedef boost::graph_traits< HalfedgeGraph > GraphTraits;
108  //typedef typename GraphTraits::vertex_iterator vertex_iterator;
110 
112  UserParam user(*user_dist);
114 
115 
116  // Note: the property maps must be extracted from the
117  // property maps bag, and explicitely passed as
118  // parameters to the filter, in order to make
119  // clear what property is used by the filter
120 
121  // retrieve point property map (aka geometry)
122  auto pm = get(boost::vertex_point, *_m);
123 
124  // retrieve or create vertex-color property map
125  using VertexColorMap =
127  HalfedgeGraph >::pmap_type;
128  typedef typename boost::property_traits< VertexColorMap >::value_type Color;
129  VertexColorMap v_cm;
130  if(has_map(*pmaps_bag, FEVV::vertex_color))
131  {
132  std::cout << "use existing vertex-color map" << std::endl;
133  v_cm = get_property_map(FEVV::vertex_color, *_m, *pmaps_bag);
134  }
135  else
136  {
137  std::cout << "create vertex-color map" << std::endl;
139  // store property map in property maps bag
140  put_property_map(FEVV::vertex_color, *_m, *pmaps_bag, v_cm);
141  }
142 
143  // retrieve or create vertex-normal property map
144  using FaceNormalMap =
146  HalfedgeGraph >::pmap_type;
147  FaceNormalMap f_nm;
148  if(has_map(*pmaps_bag, FEVV::face_normal))
149  {
150  std::cout << "use existing face-normal map" << std::endl;
151  f_nm = get_property_map(FEVV::face_normal, *_m, *pmaps_bag);
152  }
153  else
154  {
155  std::cout << "create face-normal map" << std::endl;
157  // store property map in property maps bag
158  put_property_map(FEVV::face_normal, *_m, *pmaps_bag, f_nm);
160  }
161 
162  // retrieve or create vertex-normal property map
163  using VertexNormalMap =
165  HalfedgeGraph >::pmap_type;
166  VertexNormalMap v_nm;
167  if(has_map(*pmaps_bag, std::string("v:normal")))
168  {
169  std::cout << "use existing vertex-normal map" << std::endl;
170  v_nm = boost::any_cast< VertexNormalMap >(pmaps_bag->at("v:normal"));
171  }
172  else
173  {
174  std::cout << "create vertex-normal map" << std::endl;
176  // store property map in property maps bag
177  put_property_map(FEVV::vertex_normal, *_m, *pmaps_bag, v_nm);
178  FEVV::Filters::calculate_vertex_normals(*_m, pm, f_nm, v_nm);
179  }
180 
181  using JndTypeMap =
183  JndTypeMap jnd_m;
184  clock_t tStart = clock();
185 
186  if(has_map(*pmaps_bag, std::string("v:jnd")) && !*force_jnd)
187  {
188  std::cout << "use existing jnd map" << std::endl;
189  jnd_m = boost::any_cast< JndTypeMap >(pmaps_bag->at("v:jnd"));
190  }
191  else
192  {
193  jnd_m = FEVV::make_vertex_property_map< HalfedgeGraph, double >(*_m);
194  std::cout << "computing jnd map" << std::endl;
196  *_m, pm, v_nm, f_nm, jnd_m, screen, user, scene, *number_of_lights);
197  (*pmaps_bag)["v:jnd"] = jnd_m;
198  }
199  clock_t tJND = clock();
200 
201  double min_jnd = 10000.0;
202  double max_jnd = 0.0;
203 
204  BOOST_FOREACH(vertex_descriptor vi, vertices(*_m))
205  {
206  auto jnd = get(jnd_m, vi);
207  if(min_jnd > jnd)
208  min_jnd = jnd;
209  if(max_jnd < jnd)
210  max_jnd = jnd;
211  }
212  clock_t tMM = clock();
213 
214  BOOST_FOREACH(vertex_descriptor vi, vertices(*_m))
215  {
216  auto jnd = get(jnd_m, vi);
217  double color;
218  if(*use_log)
219  color = 2.0 * ((std::log((*log_disp + jnd))) /
220  (std::log((*log_disp + max_jnd)))) -
221  1.0;
222  else
223  color = 2.0 * ((jnd - min_jnd) / (max_jnd - min_jnd)) - 1.0;
224  Color newcolor(red(color), green(color), blue(color));
225  put(v_cm, vi, newcolor);
226  }
227 
228  std::cout << "Time used to compute JND : "
229  << (double)(tJND - tStart) / CLOCKS_PER_SEC << std::endl;
230  std::cout << "Time used to compute minmax : "
231  << (double)(tMM - tJND) / CLOCKS_PER_SEC << std::endl;
232  std::cout << "Time used to compute colors : "
233  << (double)(clock() - tMM) / CLOCKS_PER_SEC << std::endl;
234  std::cout << "JND min : " << min_jnd << std::endl;
235  std::cout << "JND max : " << max_jnd << std::endl;
236  }
237 
238 
239  template< typename HalfedgeGraph >
240  void applyHG(BaseAdapterVisu *_adapter,
241  HalfedgeGraph *_mesh,
242  FEVV::PMapsContainer *pmaps_bag)
243  {
244  // get filter parameters from dialog window
245  DialogJnd1 dial1;
246  if(dial1.exec() == QDialog::Accepted)
247  {
248  dial1.getProcess(*screen_width,
249  *screen_height,
250  *screen_size,
251  *scene_height,
252  *scene_fov,
253  *user_dist,
255  *log_disp,
256  *use_log,
257  *force_jnd);
258 
259  *scene_fov = M_PI * *scene_fov;
260  }
261  else
262  return; // abort applying filter
263 
264  // apply filter
265  process(_mesh, pmaps_bag);
266 
267  // redraw mesh
268  SimpleViewer *viewer =
269  dynamic_cast< SimpleViewer * >(_adapter->getViewer());
270 
271  if(viewer)
272  {
273  viewer->draw_or_redraw_mesh(_mesh, pmaps_bag, true, false);
274  }
275 
276  reset();
277 
278 #if(FEVV_USE_QT5)
279  // empty
280 #else
281  viewer->frame(); // necessary or not ?
282 #endif
283  }
284 
285 #ifdef FEVV_USE_OPENMESH
286  void apply(BaseAdapterVisu *_adapter,
287  MeshOpenMesh *_mesh,
288  FEVV::PMapsContainer *pmaps_bag) override
289  {
290  applyHG< MeshOpenMesh >(_adapter, _mesh, pmaps_bag);
291  }
292 #endif
293 
294 #ifdef FEVV_USE_CGAL
295  void apply(BaseAdapterVisu *_adapter,
296  MeshLCC *_mesh,
297  FEVV::PMapsContainer *pmaps_bag) override
298  {
299  applyHG< MeshLCC >(_adapter, _mesh, pmaps_bag);
300  }
301 
302  void apply(BaseAdapterVisu *_adapter,
303  MeshSurface *_mesh,
304  FEVV::PMapsContainer *pmaps_bag) override
305  {
306  applyHG< MeshSurface >(_adapter, _mesh, pmaps_bag);
307  }
308 
309  void apply(BaseAdapterVisu *_adapter,
310  MeshPolyhedron *_mesh,
311  FEVV::PMapsContainer *pmaps_bag) override
312  {
313  applyHG< MeshPolyhedron >(_adapter, _mesh, pmaps_bag);
314  }
315 #endif
316 
317 #ifdef FEVV_USE_AIF
318  void apply(BaseAdapterVisu *_adapter,
319  MeshAIF *_mesh,
320  FEVV::PMapsContainer *pmaps_bag) override
321  {
322  applyHG< MeshAIF >(_adapter, _mesh, pmaps_bag);
323  }
324 #endif
325 
326 
327  QStringList Generic_plugins() const override
328  {
329  return QStringList() << "JndPlugin";
330  }
331 
332  bool Generic_plugin(const QString &/*plugin*/) override
333  {
334  SimpleWindow *sw = static_cast< SimpleWindow * >(window);
335  // dynamic_cast fails under OS X
336  sw->onModificationParam("jnd_qt_p", this);
337  sw->onApplyButton();
338 
339  return true;
340  }
341 
342 signals:
343  void resetSignal();
344 
345 protected:
346  int *screen_width = new int(1920);
347  int *screen_height = new int(1080);
348  double *screen_size = new double(55.);
349  double *user_dist = new double(50.);
350  int *scene_height = new int(1080);
351  double *scene_fov = new double(M_PI * 0.3333);
352  int *number_of_lights = new int(128);
353  float *log_disp = new float(0.5);
354  bool *use_log = new bool(true);
355  bool *force_jnd = new bool(true);
356 
357  double interpolate(double val, double y0, double x0, double y1, double x1)
358  {
359  return (val - x0) * (y1 - y0) / (x1 - x0) + y0;
360  }
361 
362  double base(double val)
363  {
364  if(val >= 1.0)
365  return 1.0;
366  else if(val > 0.0)
367  return (1.0 - val);
368  else
369  return 0.0;
370  }
371 
372  double red(double gray) { return base(1.0 + gray); }
373  double green(double gray) { return base(1.0 - fabs(gray)); }
374  double blue(double gray) { return base(1.0 - gray); }
375 };
376 
377 } // namespace FEVV
378 
FEVV::BaseWindow::isInit
virtual bool isInit() const
Definition: BaseWindow.h:103
FEVV::JndPlugin::scene_fov
double * scene_fov
Definition: JndPlugin.h:351
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::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::face_normal_t
face_normal_t
Definition: properties.h:77
FEVV::JndPlugin::applyHG
void applyHG(BaseAdapterVisu *_adapter, HalfedgeGraph *_mesh, FEVV::PMapsContainer *pmaps_bag)
Definition: JndPlugin.h:240
FEVV::JndPlugin::force_jnd
bool * force_jnd
Definition: JndPlugin.h:355
FEVV::get_property_map
PMap_traits< PropertyT, MeshT >::pmap_type get_property_map(PropertyT p, const MeshT &, const PMapsContainer &pmaps)
Definition: properties.h:646
FEVV::JndPlugin::green
double green(double gray)
Definition: JndPlugin.h:373
FEVV::DialogJnd1::getProcess
void getProcess(int &screenH, int &screenW, double &screenS, int &sceneH, double &sceneFov, double &userD, int &nbLights, float &log_disp, bool &use_log, bool &force_jnd)
Definition: DialogJnd1.cpp:31
UserParam
The parameters of the user.
Definition: types.h:43
FEVV::SimpleWindow::onApplyButton
void onApplyButton()
Definition: SimpleWindow.inl:525
just_noticeable_distortion.hpp
FEVV::MeshLCC
CGAL::Linear_cell_complex_for_combinatorial_map< 2, 3, CGALLCCTraits, CGALItem > MeshLCC
Definition: DataStructures_cgal_linear_cell_complex.h:43
FEVV::JndPlugin::screen_height
int * screen_height
Definition: JndPlugin.h:347
ScreenParam
The parameters of the screen.
Definition: types.h:27
FEVV::has_map
bool has_map(const PMapsContainer &pmaps, const std::string &map_name)
(refer to Property Maps API)
Definition: properties.h:103
FEVV::JndPlugin::base
double base(double val)
Definition: JndPlugin.h:362
FEVV::BasePluginQt
This class is intended to provide some standard message boxes to all plugins.
Definition: BasePluginQt.h:30
SimpleWindow.h
FEVV::JndPlugin::use_log
bool * use_log
Definition: JndPlugin.h:354
FEVV::JndPlugin::log_disp
float * log_disp
Definition: JndPlugin.h:353
FEVV::BaseAdapterVisu::getViewer
virtual Viewer * getViewer()
Definition: BaseAdapterVisu.h:130
FEVV::JndPlugin::process
void process(HalfedgeGraph *_m, FEVV::PMapsContainer *pmaps_bag)
Definition: JndPlugin.h:104
SceneParam
The parameters of the scene.
Definition: types.h:55
properties_linear_cell_complex.h
FEVV::MeshSurface
CGAL::Surface_mesh< CGALPoint > MeshSurface
Definition: DataStructures_cgal_surface_mesh.h:23
FEVV::BaseAdapterVisu
Definition: BaseAdapterVisu.h:27
properties_aif.h
FEVV::SimpleWindow
SimpleWindow is a specialization of QMainWindow. This class the Main Window.
Definition: SimpleWindow.h:80
FEVV::PMapsContainer
std::map< std::string, boost::any > PMapsContainer
Definition: properties.h:99
FEVV::SimpleViewer::draw_or_redraw_mesh
void draw_or_redraw_mesh(HalfedgeGraph *_g, PMapsContainer *_pmaps, bool _redraw=false, bool _recomputeNT_if_redraw=false, std::string _mesh_filename=std::string(""), bool _recreateOSGobj_if_redraw=true, float _step=0.)
Definition: SimpleViewer.inl:3415
FEVV::vertex_normal_t
vertex_normal_t
Definition: properties.h:35
FEVV::JndPlugin::Generic_plugins
QStringList Generic_plugins() const override
Definition: JndPlugin.h:327
FEVV::Assoc_property_map
Definition: properties.h:236
FEVV::JndPlugin::reset
void reset() override
Definition: JndPlugin.h:86
FEVV::JndPlugin::resetSignal
void resetSignal()
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::JndPlugin::init
void init() override
Definition: JndPlugin.h:73
FEVV::SimpleViewer
SimpleViewer is a specialization of osgViewer::CompositeViewer. This class is a widget where we are a...
Definition: SimpleViewer.h:180
properties_polyhedron_3.h
FEVV::vertex_color_t
vertex_color_t
Definition: properties.h:47
FEVV::SimpleWindow::onModificationParam
void onModificationParam(std::string _pluginName, BasePlugin *_plugin)
Definition: SimpleWindow.inl:505
FEVV::JndPlugin::screen_size
double * screen_size
Definition: JndPlugin.h:348
FEVV::JndPlugin::user_dist
double * user_dist
Definition: JndPlugin.h:349
FEVV
Interfaces for plugins These interfaces will be used for different plugins.
Definition: Assert.h:16
FEVV::JndPlugin::JndPlugin
JndPlugin()=default
FEVV::JndPlugin::red
double red(double gray)
Definition: JndPlugin.h:372
properties_surface_mesh.h
FEVV::Color
Definition: Color.hpp:18
FEVV::DialogJnd1
Definition: DialogJnd1.h:23
FEVV::vertex_color
@ vertex_color
Definition: properties.h:47
SimpleViewer.h
FEVV::Filters::calculate_face_normals
void calculate_face_normals(const HalfedgeGraph &g, const PointMap &pm, FaceNormalMap fnm, const GeometryTraits &gt)
Calculate "some" normal of all the faces of the considered mesh and populate the argument provided Fa...
Definition: calculate_face_normals.hpp:40
FEVV::JndPlugin::~JndPlugin
~JndPlugin()=default
FEVV::JndPlugin::blue
double blue(double gray)
Definition: JndPlugin.h:374
BasePluginQt.h
properties_openmesh.h
FEVV::JndPlugin::interpolate
double interpolate(double val, double y0, double x0, double y1, double x1)
Definition: JndPlugin.h:357
FEVV::Filters::calculate_vertex_normals
void calculate_vertex_normals(const HalfedgeGraph &g, const PointMap &pm, const FaceNormalMap &fnm, VertexNormalMap vnm, const GeometryTraits &gt)
Compute the respectice vertex normal for all the vertices of the considered mesh and populate the arg...
Definition: calculate_vertex_normals.hpp:41
FEVV::JndPlugin::Generic_plugin
bool Generic_plugin(const QString &) override
Definition: JndPlugin.h:332
msdm2::vertex_descriptor
boost::graph_traits< MeshT >::vertex_descriptor vertex_descriptor
Definition: msdm2_surfacemesh.h:33
FEVV::Filters::fabs
double fabs(const v_Curv< HalfedgeGraph > &input)
Definition: curvature.hpp:54
FEVV::MeshOpenMesh
OpenMesh::PolyMesh_ArrayKernelT< MyTraits > MeshOpenMesh
Definition: DataStructures_openmesh.h:51
FEVV::JndPlugin
Definition: JndPlugin.h:59
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::Generic_PluginInterface
Definition: PluginInterface.h:37
FEVV::JndPlugin::screen_width
int * screen_width
Definition: JndPlugin.h:346
FEVV::BasePluginQt::apply
virtual void apply(BaseAdapterVisu *, void *, FEVV::PMapsContainer *) override
Definition: BasePluginQt.h:108
PluginInterface.h
FEVV::_PMap_traits
Definition: properties.h:376
FEVV::BasePlugin::window
BaseWindow * window
Definition: BasePlugin.h:138
FEVV::BaseWindow
Definition: BaseWindow.h:25
properties.h
FEVV::Filters::just_noticeable_distortion_filter
void just_noticeable_distortion_filter(const HalfedgeGraph &halfedge_graph, PointMap &point_map, const VertexNormalMap &vertex_normal_map, const GeometryTraits &geometry_traits, const FaceNormalMap &face_normal_map, JNDMap &jnd_map, const ScreenParam &screen, const UserParam &user, const SceneParam &scene, const int nb_light_sources, bool data_output=false, bool use_random=true)
Computes the Just Noticeable Distortion metric.
Definition: just_noticeable_distortion.hpp:336
DialogJnd1.h
FEVV::vertex_normal
@ vertex_normal
Definition: properties.h:35
FEVV::JndPlugin::scene_height
int * scene_height
Definition: JndPlugin.h:350
FEVV::MeshPolyhedron
CGAL::Polyhedron_3< CGALKernel, CGAL::Polyhedron_items_with_id_3 > MeshPolyhedron
Definition: DataStructures_cgal_polyhedron_3.h:33
FEVV::JndPlugin::number_of_lights
int * number_of_lights
Definition: JndPlugin.h:352
FEVV::JndPlugin::addParameters
void addParameters(BaseWindow *_window) override
Definition: JndPlugin.h:93
FEVV::make_property_map
PMap_traits< PropertyT, MeshT >::pmap_type make_property_map(PropertyT, const MeshT &m)
Definition: properties.h:630
FEVV::MeshAIF
FEVV::DataStructures::AIF::AIFMesh MeshAIF
Definition: DataStructures_aif.h:19
FEVV::face_normal
@ face_normal
Definition: properties.h:77