RINGMesh  Version 5.0.0
A programming library for geological model meshes
geomodel_mesh_entity.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 
41 #pragma once
42 
43 #include <ringmesh/basic/common.h>
44 
48 
49 #include <ringmesh/mesh/mesh.h>
50 
51 namespace RINGMesh
52 {
53  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelGeologicalEntity );
54  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelMeshEntityConstAccess );
55  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderTopologyBase );
56  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderTopology );
57  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderGeometryBase );
58  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderGeometry );
59  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderGeology );
60  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderRemovalBase );
61  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderRemoval );
62  FORWARD_DECLARATION_DIMENSION_CLASS( GeoModelBuilderInfo );
64 
65  ALIAS_2D_AND_3D( GeoModel );
66 } // namespace RINGMesh
67 
68 namespace RINGMesh
69 {
76  template < index_t DIMENSION >
77  class RINGMESH_API GeoModelMeshEntity : public GeoModelEntity< DIMENSION >
78  {
81  friend class GeoModelMeshEntityAccess< DIMENSION >;
82  friend class GeoModelMeshEntityConstAccess< DIMENSION >;
83 
84  public:
85  virtual ~GeoModelMeshEntity();
86 
87  virtual MeshEntityType type_name() const = 0;
88 
89  gmme_id gmme() const
90  {
91  return gmme_id( type_name(), this->index() );
92  }
94  {
95  return gmme().type();
96  }
100  bool is_valid() const final
101  {
102  return is_mesh_valid() && are_geomodel_vertex_indices_valid();
103  }
109  virtual bool is_connectivity_valid() const;
110 
115  bool is_parent_connectivity_valid() const;
116 
121  index_t nb_boundaries() const
122  {
123  return static_cast< index_t >( boundaries_.size() );
124  }
125  const gmme_id& boundary_gmme( index_t x ) const;
126  const GeoModelMeshEntity< DIMENSION >& boundary( index_t x ) const;
127 
128  index_t nb_incident_entities() const
129  {
130  return static_cast< index_t >( incident_entities_.size() );
131  }
132  const gmme_id& incident_entity_gmme( index_t x ) const;
133  const GeoModelMeshEntity< DIMENSION >& incident_entity(
134  index_t x ) const;
135 
139  bool has_inside_border() const;
146  bool is_inside_border( const GeoModelMeshEntity& rhs ) const;
147 
152  bool has_parent() const
153  {
154  return nb_parents() != 0;
155  }
156 
160  bool has_parent( const GeologicalEntityType& parent_type ) const
161  {
162  return could_be_undefined_parent_gmge( parent_type ).is_defined();
163  }
164 
165  index_t nb_parents() const
166  {
167  return static_cast< index_t >( parents_.size() );
168  }
169 
170  const gmge_id& parent_gmge( index_t id ) const;
171 
184  const gmge_id parent_gmge(
185  const GeologicalEntityType& parent_type ) const;
187  index_t parent_index ) const;
189  const GeologicalEntityType& parent_type ) const;
190 
195  void save( const std::string& filename ) const
196  {
197  mesh_->save_mesh( filename );
198  }
204  {
205  return mesh_->vertex_nn_search();
206  }
207 
213  index_t nb_vertices() const
214  {
215  return mesh_->nb_vertices();
216  }
220  const vecn< DIMENSION >& vertex( index_t vertex_index ) const
221  {
222  return mesh_->vertex( vertex_index );
223  }
224 
232  virtual index_t nb_mesh_elements() const = 0;
236  virtual index_t nb_mesh_element_vertices(
237  index_t mesh_element_index ) const = 0;
247  virtual index_t mesh_element_vertex_index(
248  const ElementLocalVertex& element_local_vertex ) const = 0;
259  const ElementLocalVertex& element_local_vertex ) const
260  {
261  return vertex( mesh_element_vertex_index( element_local_vertex ) );
262  }
263 
269  virtual double mesh_element_size(
270  index_t mesh_element_index ) const = 0;
271  virtual vecn< DIMENSION > mesh_element_barycenter(
272  index_t mesh_element_index ) const = 0;
274  {
275  vecn< DIMENSION > result;
276  for( auto v : range( nb_vertices() ) )
277  {
278  result += vertex( v );
279  }
280  ringmesh_assert( nb_vertices() > 0 );
281  return result / static_cast< double >( nb_vertices() );
282  }
283 
284  virtual double size() const
285  {
286  double size = 0.0;
287  for( auto i : range( nb_mesh_elements() ) )
288  {
289  size += mesh_element_size( i );
290  }
291  return size;
292  }
293 
296  GEO::AttributesManager& vertex_attribute_manager() const
297  {
298  return mesh_->vertex_attribute_manager();
299  }
300 
301  protected:
302  GeoModelMeshEntity( const GeoModel< DIMENSION >& geomodel, index_t id )
303  : GeoModelEntity< DIMENSION >( geomodel, id )
304  {
305  }
307  virtual void copy_mesh_entity(
308  const GeoModelMeshEntity< DIMENSION >& from )
309  {
310  this->copy_name( from );
311  this->id_ = from.index();
312  boundaries_ = from.boundaries_;
313  incident_entities_ = from.incident_entities_;
314  parents_ = from.parents_;
315  }
316 
317  virtual bool is_index_valid() const final;
318  virtual bool is_mesh_valid() const
319  {
320  return mesh_ != nullptr;
321  }
323  void set_mesh( std::shared_ptr< MeshBase< DIMENSION > > mesh )
324  {
325  ringmesh_assert( mesh != nullptr );
326  mesh_ = std::move( mesh );
327  }
328 
333  bool is_boundary_connectivity_valid() const;
340  bool is_incident_entity_connectivity_valid() const;
347  bool are_geomodel_vertex_indices_valid() const;
348 
349  void unbind_vertex_mapping_attribute() const;
350  void bind_vertex_mapping_attribute() const;
351 
352  virtual void change_mesh_data_structure( const MeshType& type ) = 0;
353 
354  private:
355  gmge_id defined_parent_gmge(
356  const GeologicalEntityType& parent_type ) const;
357 
358  gmge_id could_be_undefined_parent_gmge(
359  const GeologicalEntityType& parent_type ) const;
360 
361  protected:
363  std::vector< index_t > boundaries_{};
364 
366  std::vector< index_t > incident_entities_{};
367 
369  std::vector< index_t > parents_{};
370 
371  private:
373  std::shared_ptr< MeshBase< DIMENSION > > mesh_{};
374  };
376 
381  template < index_t DIMENSION >
382  class RINGMESH_API Corner final : public GeoModelMeshEntity< DIMENSION >
383  {
386 
387  public:
388  friend class GeoModelMeshEntityAccess< DIMENSION >;
389  friend class GeoModelMeshEntityConstAccess< DIMENSION >;
390 
391  virtual ~Corner()
392  {
393  this->unbind_vertex_mapping_attribute();
394  }
395 
397  {
398  return MeshEntityType( "Corner" );
399  }
400 
401  MeshEntityType type_name() const final
402  {
403  return type_name_static();
404  }
405 
410  bool is_on_voi() const final;
411 
415  index_t nb_mesh_elements() const final
416  {
417  return 0;
418  }
419 
423  index_t nb_mesh_element_vertices( index_t mesh_element = 0 ) const final
424  {
425  ringmesh_unused( mesh_element );
426  index_t nb_vertices = point_set_mesh_->nb_vertices();
427  ringmesh_assert( nb_vertices < 2 );
428  return nb_vertices;
429  }
430 
431  const Line< DIMENSION >& incident_entity( index_t x ) const;
432 
437  double mesh_element_size( index_t mesh_element = 0 ) const final
438  {
439  ringmesh_unused( mesh_element );
440  return 0.0;
441  }
442 
443  double size() const final
444  {
445  return 0.0;
446  }
447 
449  index_t mesh_element = 0 ) const final
450  {
451  ringmesh_unused( mesh_element );
452  return this->vertex( 0 );
453  }
454 
459  {
460  return *point_set_mesh_;
461  }
462 
463  protected:
467  Corner( const GeoModel< DIMENSION >& geomodel,
468  index_t id,
469  const MeshType& type )
470  : GeoModelMeshEntity< DIMENSION >( geomodel, id )
471  {
472  update_mesh_storage_type(
474  }
475 
481  const ElementLocalVertex& element_local_vertex = ElementLocalVertex(
482  0, 0 ) ) const final
483  {
484  ringmesh_unused( element_local_vertex );
485  return 0;
486  }
487 
491  bool is_mesh_valid() const final;
492 
493  private:
495  std::unique_ptr< PointSetMesh< DIMENSION > > mesh )
496  {
497  point_set_mesh_ = std::move( mesh );
499  }
500 
501  void change_mesh_data_structure( const MeshType& type ) final;
502 
503  private:
504  std::shared_ptr< PointSetMesh< DIMENSION > > point_set_mesh_{};
505  };
507 
514  template < index_t DIMENSION >
515  class RINGMESH_API Line final : public GeoModelMeshEntity< DIMENSION >
516  {
519 
520  public:
521  friend class GeoModelMeshEntityAccess< DIMENSION >;
522 
523  virtual ~Line()
524  {
525  this->unbind_vertex_mapping_attribute();
526  }
527 
529  {
530  return MeshEntityType( "Line" );
531  }
532 
533  MeshEntityType type_name() const final
534  {
535  return type_name_static();
536  }
537 
538  bool is_on_voi() const final;
539 
540  const Corner< DIMENSION >& boundary( index_t x ) const;
541 
542  const Surface< DIMENSION >& incident_entity( index_t x ) const
543  {
544  return static_cast< const Surface< DIMENSION >& >(
546  }
547 
548  bool is_connectivity_valid() const final;
549 
551  {
552  return line_mesh_->edge_aabb();
553  }
554 
560  {
561  return line_mesh_->edge_nn_search();
562  }
563 
567  index_t nb_mesh_elements() const final
568  {
569  return line_mesh_->nb_edges();
570  }
571 
575  index_t nb_mesh_element_vertices( index_t mesh_element = 0 ) const final
576  {
577  ringmesh_unused( mesh_element );
578  return 2;
579  }
580 
586  const ElementLocalVertex& element_local_vertex ) const final
587  {
589  element_local_vertex.element_id_ < nb_mesh_elements() );
590  ringmesh_assert( element_local_vertex.local_vertex_id_ < 2 );
591  return line_mesh_->edge_vertex( element_local_vertex );
592  }
593 
597  bool is_closed() const
598  {
599  ringmesh_assert( this->nb_boundaries() == 2 );
600  return ( this->boundary_gmme( 0 ).is_defined() )
601  && ( this->boundary_gmme( 0 ) == this->boundary_gmme( 1 ) );
602  }
603 
607  double mesh_element_size( index_t edge_index ) const final
608  {
609  ringmesh_assert( edge_index < nb_mesh_elements() );
610  return line_mesh_->edge_length( edge_index );
611  }
612 
617  index_t edge_index ) const final
618  {
619  ringmesh_assert( edge_index < nb_mesh_elements() );
620  return line_mesh_->edge_barycenter( edge_index );
621  }
622 
623  bool is_first_corner_first_vertex() const;
624 
629  {
630  return *line_mesh_;
631  }
632 
633  protected:
634  Line( const GeoModel< DIMENSION >& geomodel,
635  index_t id,
636  const MeshType& type )
637  : GeoModelMeshEntity< DIMENSION >( geomodel, id )
638  {
639  update_mesh_storage_type(
641  }
642 
658  bool is_mesh_valid() const final;
659 
660  private:
662  std::unique_ptr< LineMesh< DIMENSION > > mesh )
663  {
664  line_mesh_ = std::move( mesh );
666  }
667 
668  void change_mesh_data_structure( const MeshType& type ) final;
669 
670  private:
671  std::shared_ptr< LineMesh< DIMENSION > > line_mesh_{};
672  };
674 
681  template < index_t DIMENSION >
682  class RINGMESH_API SurfaceBase : public GeoModelMeshEntity< DIMENSION >
683  {
686 
687  public:
688  friend class GeoModelMeshEntityAccess< DIMENSION >;
689 
690  virtual ~SurfaceBase()
691  {
692  this->unbind_vertex_mapping_attribute();
693  }
694 
695  MeshEntityType type_name() const final
696  {
697  return type_name_static();
698  }
699 
701  {
702  return MeshEntityType( "Surface" );
703  }
704 
705  const Line< DIMENSION >& boundary( index_t x ) const;
706 
707  const Region< DIMENSION >& incident_entity( index_t x ) const;
708 
709  bool is_simplicial() const
710  {
711  return surface_mesh_->polygons_are_simplicies();
712  }
713 
715  {
716  return surface_mesh_->polygon_aabb();
717  }
718 
724  {
725  return surface_mesh_->polygon_nn_search();
726  }
727 
728  GEO::AttributesManager& polygon_attribute_manager() const
729  {
730  return surface_mesh_->polygon_attribute_manager();
731  }
732 
740  index_t nb_mesh_elements() const final
741  {
742  return surface_mesh_->nb_polygons();
743  }
744 
748  index_t nb_mesh_element_vertices( index_t polygon_index ) const final
749  {
750  ringmesh_assert( polygon_index < nb_mesh_elements() );
751  return surface_mesh_->nb_polygon_vertices( polygon_index );
752  }
753 
759  const ElementLocalVertex& element_local_vertex ) const final
760  {
762  element_local_vertex.element_id_ < nb_mesh_elements() );
763  ringmesh_assert( element_local_vertex.local_vertex_id_
764  < nb_mesh_element_vertices(
765  element_local_vertex.element_id_ ) );
766  return surface_mesh_->polygon_vertex( element_local_vertex );
767  }
768 
777  const PolygonLocalEdge& polygon_local_edge ) const
778  {
780  polygon_local_edge.polygon_id_ < nb_mesh_elements() );
782  polygon_local_edge.local_edge_id_
783  < nb_mesh_element_vertices( polygon_local_edge.polygon_id_ ) );
784  return surface_mesh_->polygon_adjacent( polygon_local_edge );
785  }
786 
794  index_t polygon_index ) const final
795  {
796  ringmesh_assert( polygon_index < nb_mesh_elements() );
797  return surface_mesh_->polygon_barycenter( polygon_index );
798  }
799 
803  double mesh_element_size( index_t polygon_index ) const final
804  {
805  ringmesh_assert( polygon_index < nb_mesh_elements() );
806  return surface_mesh_->polygon_area( polygon_index );
807  }
808 
813  {
814  return *surface_mesh_;
815  }
816 
817  protected:
819  index_t id,
820  const MeshType type )
821  : GeoModelMeshEntity< DIMENSION >( geomodel, id )
822  {
823  update_mesh_storage_type(
825  }
826 
849  bool is_mesh_valid() const final;
850 
851  private:
853  std::unique_ptr< SurfaceMesh< DIMENSION > > mesh )
854  {
855  surface_mesh_ = std::move( mesh );
857  }
858 
859  void change_mesh_data_structure( const MeshType& type ) final;
860 
861  private:
862  std::shared_ptr< SurfaceMesh< DIMENSION > > surface_mesh_{};
863  };
864 
865  template < index_t DIMENSION >
866  class RINGMESH_API Surface final : public SurfaceBase< DIMENSION >
867  {
868  };
869 
870  template <>
871  class RINGMESH_API Surface< 2 > final : public SurfaceBase< 2 >
872  {
873  friend class GeoModelMeshEntityAccess< 2 >;
874 
875  private:
876  Surface( const GeoModel2D& geomodel, index_t id, const MeshType type )
877  : SurfaceBase< 2 >( geomodel, id, type )
878  {
879  }
880 
881  public:
882  bool is_on_voi() const final;
883  bool side( index_t i ) const
884  {
885  return sides_[i];
886  }
887 
891  bool is_meshed() const
892  {
893  return mesh().nb_polygons() > 0;
894  }
895 
896  private:
901  std::vector< bool > sides_{};
902  };
903 
904  template <>
905  class RINGMESH_API Surface< 3 > final : public SurfaceBase< 3 >
906  {
907  friend class GeoModelMeshEntityAccess< 3 >;
908 
909  private:
910  Surface( const GeoModel3D& geomodel, index_t id, const MeshType type )
911  : SurfaceBase< 3 >( geomodel, id, type )
912  {
913  }
914 
915  public:
916  bool is_on_voi() const final;
917  const Region< 3 >& incident_entity( index_t x ) const;
918  };
920 
929  template < index_t DIMENSION >
930  class RINGMESH_API Region final : public GeoModelMeshEntity< DIMENSION >
931  {
933  ringmesh_template_assert_3d( DIMENSION );
934 
935  public:
936  friend class GeoModelMeshEntityAccess< DIMENSION >;
937 
938  virtual ~Region()
939  {
940  this->unbind_vertex_mapping_attribute();
941  }
942 
944  {
945  return MeshEntityType( "Region" );
946  }
947 
948  MeshEntityType type_name() const final
949  {
950  return type_name_static();
951  }
952 
953  bool is_on_voi() const final;
954 
955  const Surface< DIMENSION >& boundary( index_t x ) const;
956 
957  bool is_connectivity_valid() const final;
958 
959  bool is_meshed() const
960  {
961  return volume_mesh_->nb_cells() > 0;
962  }
963 
964  bool is_simplicial() const
965  {
966  return volume_mesh_->cells_are_simplicies();
967  }
968 
970  {
971  return volume_mesh_->cell_aabb();
972  }
973 
979  {
980  return volume_mesh_->cell_nn_search();
981  }
982 
983  GEO::AttributesManager& cell_attribute_manager() const
984  {
985  return volume_mesh_->cell_attribute_manager();
986  }
987 
996  index_t nb_mesh_elements() const final
997  {
998  return volume_mesh_->nb_cells();
999  }
1000 
1004  index_t nb_mesh_element_vertices( index_t cell_index ) const final
1005  {
1006  if( is_meshed() )
1007  {
1008  ringmesh_assert( cell_index < nb_mesh_elements() );
1009  return volume_mesh_->nb_cell_vertices( cell_index );
1010  }
1012  return NO_ID;
1013  }
1014 
1019  const ElementLocalVertex& element_local_vertex ) const final
1020  {
1021  if( is_meshed() )
1022  {
1024  element_local_vertex.element_id_ < nb_mesh_elements() );
1025  ringmesh_assert( element_local_vertex.local_vertex_id_
1026  < nb_mesh_element_vertices(
1027  element_local_vertex.element_id_ ) );
1028  return volume_mesh_->cell_vertex( element_local_vertex );
1029  }
1031  return NO_ID;
1032  }
1033 
1038  CellType cell_type( index_t cell_index ) const
1039  {
1040  if( is_meshed() )
1041  {
1042  ringmesh_assert( cell_index < nb_mesh_elements() );
1043  return volume_mesh_->cell_type( cell_index );
1044  }
1046  return CellType::UNDEFINED;
1047  }
1048 
1049  index_t nb_cell_edges( index_t cell_index ) const
1050  {
1051  if( is_meshed() )
1052  {
1053  ringmesh_assert( cell_index < nb_mesh_elements() );
1054  return volume_mesh_->nb_cell_edges( cell_index );
1055  }
1057  return NO_ID;
1058  }
1059 
1060  index_t nb_cell_facets( index_t cell_index ) const
1061  {
1062  if( is_meshed() )
1063  {
1064  ringmesh_assert( cell_index < nb_mesh_elements() );
1065  return volume_mesh_->nb_cell_facets( cell_index );
1066  }
1068  return NO_ID;
1069  }
1070 
1072  index_t cell_index, index_t facet_index ) const
1073  {
1074  if( is_meshed() )
1075  {
1076  ringmesh_assert( cell_index < nb_mesh_elements() );
1077  ringmesh_assert( facet_index < nb_cell_facets( cell_index ) );
1078  return volume_mesh_->nb_cell_facet_vertices(
1079  CellLocalFacet( cell_index, facet_index ) );
1080  }
1082  return NO_ID;
1083  }
1084 
1086  index_t cell_index, index_t edge_index, index_t vertex_index ) const
1087  {
1088  if( is_meshed() )
1089  {
1090  ringmesh_assert( cell_index < nb_mesh_elements() );
1091  ringmesh_assert( edge_index < nb_cell_edges( cell_index ) );
1093  vertex_index < nb_mesh_element_vertices( cell_index ) );
1094  return volume_mesh_->cell_edge_vertex(
1095  cell_index, edge_index, vertex_index );
1096  }
1098  return NO_ID;
1099  }
1100 
1101  index_t cell_facet_vertex_index( index_t cell_index,
1102  index_t facet_index,
1103  index_t vertex_index ) const
1104  {
1105  if( is_meshed() )
1106  {
1107  ringmesh_assert( cell_index < nb_mesh_elements() );
1108  ringmesh_assert( facet_index < nb_cell_facets( cell_index ) );
1110  vertex_index < nb_mesh_element_vertices( cell_index ) );
1111  return volume_mesh_->cell_facet_vertex(
1112  CellLocalFacet( cell_index, facet_index ), vertex_index );
1113  }
1115  return NO_ID;
1116  }
1117 
1119  index_t cell_index, index_t facet_index ) const
1120  {
1121  if( is_meshed() )
1122  {
1123  ringmesh_assert( cell_index < nb_mesh_elements() );
1124  ringmesh_assert( facet_index < nb_cell_facets( cell_index ) );
1125  return volume_mesh_->cell_adjacent(
1126  CellLocalFacet( cell_index, facet_index ) );
1127  }
1129  return NO_ID;
1130  }
1131 
1132  ElementLocalVertex find_cell_from_colocated_vertex_if_any(
1133  const vecn< DIMENSION >& vertex_vec ) const;
1134 
1143  double mesh_element_size( index_t cell_index ) const final
1144  {
1145  if( is_meshed() )
1146  {
1147  ringmesh_assert( cell_index < nb_mesh_elements() );
1148  return volume_mesh_->cell_volume( cell_index );
1149  }
1151  return 0;
1152  }
1156  double size() const final
1157  {
1158  double result = 0.;
1159  for( auto i : range( this->nb_boundaries() ) )
1160  {
1161  const Surface< DIMENSION >& surface = boundary( i );
1162  for( auto t : range( surface.nb_mesh_elements() ) )
1163  {
1164  const vecn< DIMENSION >& p0 = surface.mesh_element_vertex(
1165  ElementLocalVertex( t, 0 ) );
1166  for( auto v :
1167  range( 1, surface.nb_mesh_element_vertices( t ) - 1 ) )
1168  {
1169  double cur_volume =
1170  ( dot( p0,
1171  cross( surface.mesh_element_vertex(
1172  ElementLocalVertex( t, v ) ),
1173  surface.mesh_element_vertex(
1174  ElementLocalVertex( t, v + 1 ) ) ) ) )
1175  / 6.;
1176  side( i ) ? result -= cur_volume : result += cur_volume;
1177  }
1178  }
1179  }
1180  return std::fabs( result );
1181  }
1186  index_t cell_index ) const final
1187  {
1188  if( is_meshed() )
1189  {
1190  ringmesh_assert( cell_index < nb_mesh_elements() );
1191  return volume_mesh_->cell_barycenter( cell_index );
1192  }
1194  return vecn< DIMENSION >();
1195  }
1196 
1197  std::vector< index_t > cells_around_vertex(
1198  index_t vertex_id, index_t cell_hint ) const
1199  {
1200  return volume_mesh_->cells_around_vertex( vertex_id, cell_hint );
1201  }
1202 
1203  bool side( index_t i ) const
1204  {
1205  return sides_[i];
1206  }
1213  const VolumeMesh< DIMENSION >& mesh() const
1214  {
1215  return *volume_mesh_;
1216  }
1217 
1218  private:
1219  Region( const GeoModel< DIMENSION >& geomodel,
1220  index_t id,
1221  const MeshType type )
1222  : GeoModelMeshEntity< DIMENSION >( geomodel, id )
1223  {
1224  update_mesh_storage_type(
1226  }
1227 
1228  bool is_mesh_valid() const final;
1230  void update_mesh_storage_type(
1231  std::unique_ptr< VolumeMesh< DIMENSION > > mesh )
1232  {
1233  volume_mesh_ = std::move( mesh );
1235  }
1236 
1237  void change_mesh_data_structure( const MeshType& type ) final;
1239  void copy_mesh_entity(
1240  const GeoModelMeshEntity< DIMENSION >& from ) final
1241  {
1242  const auto& region_from =
1243  dynamic_cast< const Region< DIMENSION >& >( from );
1245  sides_ = region_from.sides_;
1246  }
1247 
1248  protected:
1253  std::vector< bool > sides_{};
1254 
1255  private:
1256  std::shared_ptr< VolumeMesh< DIMENSION > > volume_mesh_{};
1257  };
1258 
1259  ALIAS_3D( Region );
1260 
1261  template < index_t DIMENSION >
1263  {
1265  ringmesh_template_assert_2d_or_3d( DIMENSION );
1266  friend class GeoModelBuilderGeometryBase< DIMENSION >;
1267  friend class GeoModelBuilderGeometry< DIMENSION >;
1268  friend class GeoModelBuilderTopologyBase< DIMENSION >;
1269  friend class GeoModelBuilderTopology< DIMENSION >;
1270 
1271  private:
1273  const GeoModelMeshEntity< DIMENSION >& gme )
1274  : gmme_( gme )
1275  {
1276  }
1277 
1278  ~GeoModelMeshEntityConstAccess() = default;
1279 
1280  const std::shared_ptr< MeshBase< DIMENSION > >& mesh() const
1281  {
1282  return gmme_.mesh_;
1283  }
1284 
1285  const std::vector< index_t >& incident_entity_relation_ids() const
1286  {
1287  return gmme_.incident_entities_;
1288  }
1289 
1290  const std::vector< index_t >& boundary_relation_ids() const
1291  {
1292  return gmme_.boundaries_;
1293  }
1294 
1295  private:
1297  };
1298 
1299  template < index_t DIMENSION >
1300  class RINGMESH_API GeoModelMeshEntityAccess
1301  {
1303  ringmesh_template_assert_2d_or_3d( DIMENSION );
1304  friend class GeoModelBuilderTopologyBase< DIMENSION >;
1305  friend class GeoModelBuilderTopology< DIMENSION >;
1306  friend class GeoModelBuilderGeometryBase< DIMENSION >;
1307  friend class GeoModelBuilderGeometry< DIMENSION >;
1308  friend class GeoModelBuilderGeology< DIMENSION >;
1309  friend class GeoModelBuilderInfo< DIMENSION >;
1310  friend class GeoModelBuilderRemovalBase< DIMENSION >;
1311  friend class GeoModelBuilderRemoval< DIMENSION >;
1312 
1313  private:
1316  : gmme_( gme )
1317  {
1318  }
1319 
1320  ~GeoModelMeshEntityAccess() = default;
1321 
1322  std::string& modifiable_name()
1323  {
1324  return gmme_.name_;
1325  }
1326 
1327  index_t& modifiable_index()
1328  {
1329  return gmme_.id_;
1330  }
1331 
1332  std::vector< index_t >& modifiable_boundaries()
1333  {
1334  return gmme_.boundaries_;
1335  }
1336 
1337  std::vector< index_t >& modifiable_incident_entities()
1338  {
1339  return gmme_.incident_entities_;
1340  }
1341 
1342  std::vector< bool >& modifiable_sides();
1343 
1344  std::vector< index_t >& modifiable_parents()
1345  {
1346  return gmme_.parents_;
1347  }
1348 
1349  std::shared_ptr< MeshBase< DIMENSION > >& modifiable_mesh()
1350  {
1351  return gmme_.mesh_;
1352  }
1353 
1355  {
1356  gmme_.copy_mesh_entity( from );
1357  }
1358 
1359  void change_mesh_data_structure( const MeshType& type );
1360 
1361  template < template < index_t > class ENTITY >
1362  static std::unique_ptr< ENTITY< DIMENSION > > create_entity(
1363  const GeoModel< DIMENSION >& geomodel,
1364  index_t id,
1365  const MeshType& type )
1366  {
1367  return std::unique_ptr< ENTITY< DIMENSION > >(
1368  new ENTITY< DIMENSION >( geomodel, id, type ) );
1369  }
1370 
1371  private:
1373  };
1375 } // namespace RINGMesh
std::vector< index_t > & modifiable_boundaries()
index_t nb_mesh_element_vertices(index_t mesh_element=0) const final
double size() const final
const SurfaceAABBTree< DIMENSION > & polygon_aabb() const
#define ringmesh_disable_copy_and_move(Class)
Definition: common.h:76
index_t cell_edge_vertex_index(index_t cell_index, index_t edge_index, index_t vertex_index) const
const LineAABBTree< DIMENSION > & edge_aabb() const
Surface(const GeoModel3D &geomodel, index_t id, const MeshType type)
Abstract base class for GeoModelMeshEntity.
GEO::vecng< DIMENSION, double > vecn
Definition: types.h:74
const NNSearch< DIMENSION > & polygon_nn_search() const
Return the NNSearch for the polygons of the surface.
const LineMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
double size() const final
Compute the volume of the Region.
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Index of the vertex in the Surface from its index in a polygon of the mesh.
index_t nb_cell_edges(index_t cell_index) const
MeshEntityType type_name() const final
double mesh_element_size(index_t polygon_index) const final
void save(const std::string &filename) const
const vecn< DIMENSION > & vertex(index_t vertex_index) const
Coordinates of the vertex_index.
index_t nb_cell_facets(index_t cell_index) const
const NNSearch< DIMENSION > & edge_nn_search() const
Return the NNSearch for the edges of the line.
index_t nb_mesh_element_vertices(index_t polygon_index) const final
The GeologicalEntityType described the type of the Geological entities User can defined there own Geo...
Definition: entity_type.h:137
MeshEntityType type_name() const final
bool has_parent(const GeologicalEntityType &parent_type) const
Check if the entity has a parent of the given type.
index_t nb_mesh_elements() const final
std::vector< index_t > cells_around_vertex(index_t vertex_id, index_t cell_hint) const
const PointSetMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
Corner(const GeoModel< DIMENSION > &geomodel, index_t id, const MeshType &type)
Creates a Corner. A point is added to its Mesh.
static std::unique_ptr< ENTITY< DIMENSION > > create_entity(const GeoModel< DIMENSION > &geomodel, index_t id, const MeshType &type)
const NNSearch< DIMENSION > & vertex_nn_search() const
Return the NNSearch for the Entity vertices.
void ringmesh_unused(const T &)
Definition: common.h:105
MeshEntityType type_name() const final
vecn< DIMENSION > entity_barycenter() const
GeoModelMeshEntity< DIMENSION > & gmme_
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Index of a vertex in the Region from its index in a cell.
ALIAS_3D(GeoModel)
#define ringmesh_template_assert_2d_or_3d(type)
Definition: common.h:80
A GeoModelEntity of type CORNER.
std::vector< index_t > boundaries_
Boundary relations of this entity.
CellType cell_type(index_t cell_index) const
void update_mesh_storage_type(std::unique_ptr< LineMesh< DIMENSION > > mesh)
ALIAS_2D_AND_3D(Box)
void set_mesh(std::shared_ptr< MeshBase< DIMENSION > > mesh)
static MeshEntityType type_name_static()
double mesh_element_size(index_t mesh_element=0) const final
bool is_meshed() const
Tells whether the Surface2D is meshed or not.
#define ringmesh_template_assert_3d(type)
Definition: common.h:84
bool is_closed() const
A Line is closed if its two extremities are identitical.
vecn< DIMENSION > mesh_element_barycenter(index_t mesh_element=0) const final
vecn< DIMENSION > mesh_element_barycenter(index_t edge_index) const final
Gets the barycenter of an edge.
index_t nb_mesh_element_vertices(index_t mesh_element=0) const final
void update_mesh_storage_type(std::unique_ptr< PointSetMesh< DIMENSION > > mesh)
Surface(const GeoModel2D &geomodel, index_t id, const MeshType type)
const SurfaceMesh< DIMENSION > & mesh() const
Get the low level mesh data structure.
vecn< DIMENSION > mesh_element_barycenter(index_t polygon_index) const final
static MeshEntityType type_name_static()
index_t nb_mesh_elements() const final
index_t nb_mesh_elements() const final
A GeoModelEntity of type SURFACE.
MeshEntityType type_name() const final
index_t nb_mesh_element_vertices(index_t cell_index) const final
const NNSearch< DIMENSION > & cell_nn_search() const
Return the NNSearch for the cells of the region.
const std::shared_ptr< MeshBase< DIMENSION > > & mesh() const
void copy(const GeoModelMeshEntity< DIMENSION > &from)
CellType
Definition: types.h:89
std::string MeshType
Definition: mesh.h:69
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex) const final
Get the index of a vertex in the Line from the.
double mesh_element_size(index_t edge_index) const final
Gets the length of an edge.
void update_mesh_storage_type(std::unique_ptr< SurfaceMesh< DIMENSION > > mesh)
Line(const GeoModel< DIMENSION > &geomodel, index_t id, const MeshType &type)
static MeshEntityType type_name_static()
encapsulate adimensional mesh functionalities in order to provide an API on which we base the RINGMes...
Definition: mesh.h:138
bool is_simplicial() const
index_t cell_adjacent_index(index_t cell_index, index_t facet_index) const
const Surface< DIMENSION > & incident_entity(index_t x) const
const VolumeAABBTree< DIMENSION > & cell_aabb() const
index_t mesh_element_vertex_index(const ElementLocalVertex &element_local_vertex=ElementLocalVertex(0, 0)) const final
Get the index of the unique vertex constituting of the Corner.
bool side(index_t i) const
index_t nb_cell_facet_vertices(index_t cell_index, index_t facet_index) const
GEO::AttributesManager & polygon_attribute_manager() const
vecn< DIMENSION > mesh_element_barycenter(index_t cell_index) const final
Get the center of the cell.
std::vector< index_t > & modifiable_parents()
Builder tools to remove entities from a GeoModel.
bool side(index_t i) const
#define ringmesh_assert(x)
const GeoModelMeshEntity< DIMENSION > & incident_entity(index_t x) const
bool is_valid() const final
Global validity of the entity.
GeoModelMeshEntityAccess(GeoModelMeshEntity< DIMENSION > &gme)
A GeoModelEntity of type REGION.
The MeshEntityType described the type of the meshed entities There are 4 MeshEntityTypes correspondin...
Definition: entity_type.h:117
This template is a specialization of a gme_id to the GeoModelGeologicalEntity.
Definition: entity_type.h:262
Classes to build GeoModel from various inputs.
Definition: algorithm.h:48
index_t polygon_adjacent_index(const PolygonLocalEdge &polygon_local_edge) const
Gets the polygon adjacent along an edge of a polygon.
virtual void copy_mesh_entity(const GeoModelMeshEntity< DIMENSION > &from)
A GeoModelEntity of type LINE.
Abstract base class describing one entity of a GeoModel.
const vecn< DIMENSION > & mesh_element_vertex(const ElementLocalVertex &element_local_vertex) const
Coordinates of a vertex of a mesh element.
const std::vector< index_t > & boundary_relation_ids() const
const std::vector< index_t > & incident_entity_relation_ids() const
index_t nb_mesh_elements() const final
std::vector< index_t > incident_entities_
Incident-entity relations of this entity.
static MeshEntityType type_name_static()
const GeoModelMeshEntity< DIMENSION > & gmme_
std::vector< index_t > parents_
Parents relations of this entity.
SurfaceBase(const GeoModel< DIMENSION > &geomodel, index_t id, const MeshType type)
std::vector< index_t > & modifiable_incident_entities()
index_t cell_facet_vertex_index(index_t cell_index, index_t facet_index, index_t vertex_index) const
This template is a specialization of a gme_id to the GeoModelMeshEntity.
Definition: entity_type.h:285
double mesh_element_size(index_t cell_index) const final
Volume of a cell.
FORWARD_DECLARATION_DIMENSION_CLASS(GeoModelMeshEntityAccess)
GeoModelMeshEntityConstAccess(const GeoModelMeshEntity< DIMENSION > &gme)
GEO::AttributesManager & cell_attribute_manager() const
#define ringmesh_assert_not_reached
MeshEntityType mesh_entity_type() const
std::shared_ptr< MeshBase< DIMENSION > > & modifiable_mesh()