RINGMesh  Version 5.0.0
A programming library for geological model meshes
mesh_entity_gfx.h
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2012-2017, Association Scientifique pour la Geologie et ses
3  * Applications (ASGA). All rights reserved.
4  *
5  * Redistribution and use in source and binary forms, with or without
6  * modification, are permitted provided that the following conditions are met:
7  * * Redistributions of source code must retain the above copyright
8  * notice, this list of conditions and the following disclaimer.
9  * * Redistributions in binary form must reproduce the above copyright
10  * notice, this list of conditions and the following disclaimer in the
11  * documentation and/or other materials provided with the distribution.
12  * * Neither the name of ASGA nor the
13  * names of its contributors may be used to endorse or promote products
14  * derived from this software without specific prior written permission.
15  *
16  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
17  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
18  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19  * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ASGA BE LIABLE FOR ANY DIRECT,
20  * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
21  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
22  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
23  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26  *
27  * http://www.ring-team.org
28  *
29  * RING Project
30  * Ecole Nationale Superieure de Geologie - GeoRessources
31  * 2 Rue du Doyen Marcel Roubault - TSA 70605
32  * 54518 VANDOEUVRE-LES-NANCY
33  * FRANCE
34  */
35 
36 #pragma once
37 
38 #include <ringmesh/basic/common.h>
39 
40 #ifdef RINGMESH_WITH_GRAPHICS
41 
42 #include <memory>
43 
44 #include <geogram/basic/factory.h>
45 
46 #include <geogram_gfx/glup_viewer/glup_viewer_gui.h>
47 
48 #include <ringmesh/basic/factory.h>
49 
50 #include <ringmesh/mesh/mesh.h>
51 
57 namespace RINGMesh
58 {
60  FORWARD_DECLARATION_DIMENSION_CLASS( AttributeGfxManager );
66  ALIAS_2D_AND_3D( GeoModelGfx );
67 } // namespace RINGMesh
68 
69 namespace RINGMesh
70 {
71  template < index_t DIMENSION >
72  class MeshEntityGfx
73  {
74  ringmesh_disable_copy_and_move( MeshEntityGfx );
76 
77  public:
78  virtual ~MeshEntityGfx() = default;
79 
80  virtual void draw_vertices() = 0;
81  virtual void set_vertex_color( float red, float green, float blue ) = 0;
82  virtual void set_vertex_size( index_t s ) = 0;
83 
84  virtual void set_scalar_attribute( GEO::MeshElementsFlags subelements,
85  const std::string& name,
86  double attr_min,
87  double attr_max,
88  GLuint colormap_texture ) = 0;
89  virtual void unset_scalar_attribute() = 0;
90 
91  void set_vertex_visible( bool is_visible )
92  {
93  vertex_visible_ = is_visible;
94  }
95 
96  bool get_vertex_visible() const
97  {
98  return vertex_visible_;
99  }
100 
101  protected:
102  MeshEntityGfx() = default;
103 
104  private:
105  bool vertex_visible_{ false };
106  };
107 
108  template < index_t DIMENSION >
109  class PointSetMeshGfx : public MeshEntityGfx< DIMENSION >
110  {
111  public:
112  static std::unique_ptr< PointSetMeshGfx< DIMENSION > > create_gfx(
113  const PointSetMesh< DIMENSION >& mesh );
114 
115  protected:
116  PointSetMeshGfx()
117  {
118  this->set_vertex_visible( true );
119  }
120  };
121 
122  template < index_t DIMENSION >
123  using PointSetMeshGfxFactory = Factory< MeshType,
124  PointSetMeshGfx< DIMENSION >,
125  const PointSetMesh< DIMENSION >& >;
126  ALIAS_2D_AND_3D( PointSetMeshGfxFactory );
127 
128  template < index_t DIMENSION >
129  class LineMeshGfx : public MeshEntityGfx< DIMENSION >
130  {
131  public:
132  static std::unique_ptr< LineMeshGfx< DIMENSION > > create_gfx(
133  const LineMesh< DIMENSION >& mesh );
134 
135  void set_edge_visible( bool is_visible )
136  {
137  edge_visible_ = is_visible;
138  }
139  bool get_edge_visible() const
140  {
141  return edge_visible_;
142  }
143 
144  virtual void draw_edges() = 0;
145  virtual void set_edge_color( float red, float green, float blue ) = 0;
146  virtual void set_edge_width( index_t s ) = 0;
147 
148  protected:
149  LineMeshGfx()
150  {
151  this->set_vertex_visible( false );
152  }
153 
154  private:
155  bool edge_visible_{ true };
156  };
157 
158  template < index_t DIMENSION >
159  using LineMeshGfxFactory = Factory< MeshType,
160  LineMeshGfx< DIMENSION >,
161  const LineMesh< DIMENSION >& >;
162  ALIAS_2D_AND_3D( LineMeshGfxFactory );
163 
164  template < index_t DIMENSION >
165  class SurfaceMeshGfx : public MeshEntityGfx< DIMENSION >
166  {
167  public:
168  static std::unique_ptr< SurfaceMeshGfx< DIMENSION > > create_gfx(
169  const SurfaceMesh< DIMENSION >& mesh );
170 
171  virtual void draw_surface() = 0;
172  virtual void set_surface_color(
173  float red, float green, float blue ) = 0;
174  virtual void set_backface_surface_color(
175  float red, float green, float blue ) = 0;
176  virtual void set_mesh_color( float red, float green, float blue ) = 0;
177  virtual void set_mesh_visibility( bool is_visible ) = 0;
178  virtual void set_mesh_width( index_t s ) = 0;
179 
180  void set_surface_visible( bool is_visible )
181  {
182  surface_visible_ = is_visible;
183  }
184  bool get_surface_visible() const
185  {
186  return surface_visible_;
187  }
188 
189  protected:
190  SurfaceMeshGfx()
191  {
192  this->set_vertex_visible( false );
193  }
194 
195  private:
196  bool surface_visible_{ true };
197  };
198 
199  template < index_t DIMENSION >
200  using SurfaceMeshGfxFactory = Factory< MeshType,
201  SurfaceMeshGfx< DIMENSION >,
202  const SurfaceMesh< DIMENSION >& >;
203  ALIAS_2D_AND_3D( SurfaceMeshGfxFactory );
204 
205  template < index_t DIMENSION >
206  class VolumeMeshGfx : public MeshEntityGfx< DIMENSION >
207  {
208  public:
209  static std::unique_ptr< VolumeMeshGfx< DIMENSION > > create_gfx(
210  const VolumeMesh< DIMENSION >& mesh );
211 
212  void set_region_visible( bool is_visible )
213  {
214  region_visible_ = is_visible;
215  }
216  bool get_region_visible() const
217  {
218  return region_visible_;
219  }
220 
221  virtual void draw_volume() = 0;
222  virtual void set_draw_cells( CellType type, bool x ) = 0;
223  virtual void set_cell_colors_by_type() = 0;
224  virtual void set_cells_color( float red, float green, float blue ) = 0;
225  virtual void set_mesh_color( float red, float green, float blue ) = 0;
226  virtual void set_mesh_visibility( bool b ) = 0;
227  virtual void set_mesh_width( index_t s ) = 0;
228  virtual void set_shrink( double s ) = 0;
229 
230  protected:
231  VolumeMeshGfx()
232  {
233  this->set_vertex_visible( false );
234  }
235 
236  private:
237  bool region_visible_{ true };
238  };
239 
240  template < index_t DIMENSION >
241  using VolumeMeshGfxFactory = Factory< MeshType,
242  VolumeMeshGfx< DIMENSION >,
243  const VolumeMesh< DIMENSION >& >;
244  ALIAS_2D_AND_3D( VolumeMeshGfxFactory );
245 
246 #define ringmesh_register_volume_gfx_2d( type ) \
247  geo_register_creator( RINGMesh::VolumeMeshGfxFactory2D, type##Gfx, \
248  type::type_name_static() )
249 
250 #define ringmesh_register_volume_gfx_3d( type ) \
251  geo_register_creator( RINGMesh::VolumeMeshGfxFactory3D, type##Gfx, \
252  type::type_name_static() )
253 
254  template < index_t DIMENSION >
255  class AttributeGfxManagerBase
256  {
257  ringmesh_disable_copy_and_move( AttributeGfxManagerBase );
258 
259  public:
260  virtual ~AttributeGfxManagerBase() = default;
261 
262  GeoModelGfx< DIMENSION >& gfx()
263  {
264  return gfx_;
265  }
266 
267  void compute_range();
268 
269  void unbind_attribute();
270 
271  void bind_attribute();
272 
273  void set_maximum( double max )
274  {
275  maximum_ = max;
276  }
277 
278  double maximum() const
279  {
280  return maximum_;
281  }
282 
283  void set_minimum( double min )
284  {
285  minimum_ = min;
286  }
287 
288  double minimum() const
289  {
290  return minimum_;
291  }
292 
293  void set_location( const std::string& location )
294  {
295  const auto& it = factory_.find( location );
296  if( it != factory_.end() )
297  {
298  attribute_.reset( ( *it->second )() );
299  attribute_->set_manager( *this );
300  }
301  }
302 
303  std::string location_name() const;
304 
305  index_t nb_coordinates() const;
306 
307  void set_coordinate( const index_t& coordinate )
308  {
309  coordinate_ = coordinate;
310  }
311 
312  const index_t& coordinate() const
313  {
314  return coordinate_;
315  }
316 
317  void set_name( const std::string& name )
318  {
319  name_ = name;
320  }
321 
322  const std::string& name() const
323  {
324  return name_;
325  }
326 
327  void set_colormap( GLuint colormap )
328  {
329  colormap_texture_ = colormap;
330  }
331 
332  GLuint colormap() const
333  {
334  return colormap_texture_;
335  }
336 
337  template < template < index_t > class TYPE >
338  void register_attribute_location()
339  {
340  factory_.emplace( TYPE< DIMENSION >::location_name_static(),
341  FactoryCreator::template create< TYPE< DIMENSION > > );
342  }
343 
344  std::vector< std::string > registered_locations() const
345  {
346  std::vector< std::string > locations;
347  for( const auto& location : factory_ )
348  {
349  locations.push_back( location.first );
350  }
351  return locations;
352  }
353 
354  std::vector< std::string > get_attribute_names();
355 
356  protected:
357  explicit AttributeGfxManagerBase( GeoModelGfx< DIMENSION >& gfx );
358 
359  protected:
360  GeoModelGfx< DIMENSION >& gfx_;
361 
362  std::string name_;
363  index_t coordinate_{ 0 };
364  GLuint colormap_texture_{ 0 };
365  double minimum_{ 0 };
366  double maximum_{ 0 };
367 
368  using FactoryCreator =
369  GEO::FactoryCreator0< AttributeGfx< DIMENSION > >;
370  std::map< std::string, typename FactoryCreator::CreatorType > factory_;
371  std::unique_ptr< AttributeGfx< DIMENSION > > attribute_;
372  };
373 
374  template < index_t DIMENSION >
375  class AttributeGfxManager final
376  : public AttributeGfxManagerBase< DIMENSION >
377  {
378  public:
379  explicit AttributeGfxManager( GeoModelGfx< DIMENSION >& gfx )
380  : AttributeGfxManagerBase< DIMENSION >( gfx )
381  {
382  }
383  };
384 
385  template <>
386  class RINGMESH_API AttributeGfxManager< 3 > final
387  : public AttributeGfxManagerBase< 3 >
388  {
389  public:
390  explicit AttributeGfxManager( GeoModelGfx3D& gfx );
391  };
392 
393  template < index_t DIMENSION >
394  class AttributeGfx
395  {
396  ringmesh_disable_copy_and_move( AttributeGfx );
397 
398  public:
399  AttributeGfx() = default;
400 
401  virtual ~AttributeGfx() = default;
402 
403  void set_manager( AttributeGfxManagerBase< DIMENSION >& manager )
404  {
405  manager_ = &manager;
406  }
407 
408  virtual std::string location_name() const = 0;
409  void compute_range()
410  {
411  double attribute_min = max_float64();
412  double attribute_max = min_float64();
413  do_compute_range( attribute_min, attribute_max );
414  manager_->set_minimum( attribute_min );
415  manager_->set_maximum( attribute_max );
416  }
417  std::vector< std::string > get_attribute_names()
418  {
419  const GEO::AttributesManager& attributes = get_attribute_manager();
420  GEO::vector< std::string > attribute_names;
421  attributes.list_attribute_names( attribute_names );
422  std::vector< std::string > names;
423  for( const std::string& name : attribute_names )
424  {
425  const GEO::AttributeStore* store =
426  attributes.find_attribute_store( name );
427  if( GEO::ReadOnlyScalarAttributeAdapter::can_be_bound_to(
428  store ) )
429  {
430  names.push_back( name );
431  }
432  }
433  return names;
434  }
435  virtual GEO::AttributesManager& get_attribute_manager() = 0;
436  virtual void bind_attribute() = 0;
437  virtual void unbind_attribute() = 0;
438  virtual index_t nb_coordinates() = 0;
439 
440  private:
441  virtual void do_compute_range(
442  double& attribute_min, double& attribute_max ) = 0;
443 
444  protected:
445  AttributeGfxManagerBase< DIMENSION >* manager_{ nullptr };
446  };
447 } // namespace RINGMesh
448 
449 #endif
#define ringmesh_disable_copy_and_move(Class)
Definition: common.h:76
#define ringmesh_template_assert_2d_or_3d(type)
Definition: common.h:80
ALIAS_2D_AND_3D(Box)
CellType
Definition: types.h:89
std::string MeshType
Definition: mesh.h:69
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
FORWARD_DECLARATION_DIMENSION_CLASS(GeoModelMeshEntityAccess)