Geogram Version 1.9.6-rc
A programming library of geometric algorithms
Loading...
Searching...
No Matches
mesh.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2000-2022 Inria
3 * 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 *
8 * * Redistributions of source code must retain the above copyright notice,
9 * this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 * * Neither the name of the ALICE Project-Team nor the names of its
14 * contributors may be used to endorse or promote products derived from this
15 * software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
18 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
21 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 *
29 * Contact: Bruno Levy
30 *
31 * https://www.inria.fr/fr/bruno-levy
32 *
33 * Inria,
34 * Domaine de Voluceau,
35 * 78150 Le Chesnay - Rocquencourt
36 * FRANCE
37 *
38 */
39
40#ifndef GEOGRAM_MESH_MESH
41#define GEOGRAM_MESH_MESH
42
44#include <geogram/basic/range.h>
46#include <geogram/basic/vector_attribute.h>
48#include <tuple>
49
50// GOMGEN (Graphite's pre-processor) does not understand
51// modern C++ (but it is not a big drama since it is just
52// used to generate the GUI).
53#ifdef GOMGEN
54#define MESH_NO_SYNTAXIC_SUGAR
55#endif
56
62namespace GEO {
63
64 class Mesh;
65
66 static constexpr index_t NO_VERTEX = NO_INDEX;
67 static constexpr index_t NO_EDGE = NO_INDEX;
68 static constexpr index_t NO_FACET = NO_INDEX;
69 static constexpr index_t NO_CELL = NO_INDEX;
70 static constexpr index_t NO_CORNER = NO_INDEX;
71
79 class GEOGRAM_API MeshSubElementsStore {
80 public:
81
88
93
98 index_t nb() const {
99 return nb_;
100 }
101
110 return const_cast<AttributesManager&>(attributes_);
111 }
112
118 return index_as_iterator(0);
119 }
120
126 return index_as_iterator(nb());
127 }
128
129 protected:
130
140 virtual void clear_store(
141 bool keep_attributes, bool keep_memory = false
142 );
143
150 virtual void resize_store(index_t new_size);
151
152
157 void reserve_store(index_t nb_to_reserve) {
158 index_t nb = this->nb();
159 resize_store(nb + nb_to_reserve);
160 resize_store(nb);
161 }
162
169 index_t result = nb_;
170 if(nb_ + nb > attributes_.size()) {
171 index_t new_capacity=nb_ + nb;
172 if(nb < 128) {
173 new_capacity = std::max(index_t(16),attributes_.size());
174 while(new_capacity < nb_ + nb) {
175 new_capacity *= 2;
176 }
177 }
178 attributes_.reserve(new_capacity);
179 }
180 nb_ += nb;
181 attributes_.resize(nb_);
182 return result;
183 }
184
190 index_t result = nb_;
191 ++nb_;
192 if(attributes_.capacity() < nb_) {
193 index_t new_capacity =
194 std::max(index_t(16),attributes_.capacity()*2);
195 attributes_.reserve(new_capacity);
196 }
197 attributes_.resize(nb_);
198 return result;
199 }
200
211 attributes_.resize(nb_);
212 }
213
223 void copy(
224 const MeshSubElementsStore& rhs,
225 bool copy_attributes = true
226 ) {
227 nb_ = rhs.nb();
228 if(copy_attributes) {
229 attributes_.copy(rhs.attributes_);
230 } else {
231 attributes_.clear(false,false);
232 attributes_.resize(rhs.attributes_.size());
233 }
234 }
235
236 protected:
237 Mesh& mesh_;
238 AttributesManager attributes_;
239 index_t nb_;
240 };
241
242
243 /**************************************************************************/
244
252 class GEOGRAM_API MeshElements {
253 public:
254 MeshElements();
255 virtual ~MeshElements();
256
266 virtual void delete_elements(
267 vector<index_t>& to_delete,
268 bool remove_isolated_vertices=true
269 ) = 0;
270
283 virtual void permute_elements(vector<index_t>& permutation) = 0;
284
294 virtual void clear(
295 bool keep_attributes=true, bool keep_memory=false
296 ) = 0;
297
301 virtual void pop() = 0;
302
303 protected:
311 static bool has_non_zero(const GEO::vector<index_t>& I) {
312 for(index_t i = 0; i < I.size(); i++) {
313 if(I[i] != 0) {
314 return true;
315 }
316 }
317 return false;
318 }
319 };
320
321 /**************************************************************************/
322
323 class MeshEdges;
324 class MeshFacetCornersStore;
325 class MeshCellCornersStore;
326
331 class GEOGRAM_API MeshVertices :
332 public MeshSubElementsStore, public MeshElements {
333 public:
334 MeshVertices(Mesh& mesh);
335 ~MeshVertices() override;
336
342
344 vector<index_t>& to_delete, bool remove_isolated_vertices=true
345 ) override;
346
347 void permute_elements(vector<index_t>& permutation) override;
348
354 return MeshSubElementsStore::create_sub_element();
355 }
356
362 index_t create_vertex(const double* coords) {
363 // Sanity check:
364 // It is not correct to call create_vertex(point_ptr(v)) since
365 // create_vertex may realloc the points coordinates vector, thus
366 // invalidate point_ptr(v).
368 nb() == 0 ||
369 coords < point_ptr(0) ||
370 coords >= point_ptr(0) + nb() * dimension()
371 );
372 index_t result = create_vertex();
373 for(index_t c=0; c<dimension(); ++c) {
374 point_ptr(result)[c] = coords[c];
375 }
376 return result;
377 }
378
385 template <index_t DIM> index_t create_vertex(
386 const vecng<DIM,double>& p
387 ) {
388 geo_debug_assert(dimension() == DIM);
389 return create_vertex(p.data());
390 }
391
398 return MeshSubElementsStore::create_sub_elements(nb);
399 }
400
401 void clear(
402 bool keep_attributes=true, bool keep_memory=false
403 ) override;
404
413
423
430 bool single_precision() const {
431 return point_fp32_.is_bound();
432 }
433
441 bool double_precision() const {
442 return point_.is_bound();
443 }
444
450 return
451 single_precision() ?
452 point_fp32_.dimension() :
453 point_.dimension() ;
454 }
455
463 if(single_precision()) {
464 point_fp32_.redim(dim);
465 } else {
466 point_.redim(dim);
467 }
468 }
469
477 const double* point_ptr(index_t v) const {
478 geo_debug_assert(v < nb());
479 geo_debug_assert(!single_precision());
480 return &point_[v*point_.dimension()];
481 }
482
490 double* point_ptr(index_t v) {
491 geo_debug_assert(v < nb());
492 geo_debug_assert(!single_precision());
493 return &point_[v*point_.dimension()];
494 }
495
496
504 template<index_t DIM=3> vecng<DIM,double>& point(index_t v) {
505 geo_debug_assert(v < nb());
506 geo_debug_assert(!single_precision());
507 geo_debug_assert(dimension() >= DIM);
508 return *reinterpret_cast<vecng<DIM,double>*>(
509 &point_[v*point_.dimension()]
510 );
511 }
512
520 template <index_t DIM=3> const vecng<DIM,double>& point(
521 index_t v
522 ) const {
523 geo_debug_assert(v < nb());
524 geo_debug_assert(!single_precision());
525 geo_debug_assert(dimension() >= DIM);
526 return *reinterpret_cast<const vecng<DIM,double>*>(
527 &point_[v*point_.dimension()]
528 );
529 }
530
538 const float* single_precision_point_ptr(index_t v) const {
539 geo_debug_assert(v < nb());
540 geo_debug_assert(single_precision());
541 return &point_fp32_[v*point_fp32_.dimension()];
542 }
543
552 geo_debug_assert(v < nb());
553 geo_debug_assert(single_precision());
554 return &point_fp32_[v*point_fp32_.dimension()];
555 }
556
567 vector<double>& points, index_t dim, bool steal_arg
568 );
569
579 const double* points, index_t dim, index_t nb_pts
580 );
581
582 void pop() override;
583
584#ifndef MESH_NO_SYNTAXIC_SUGAR
585
590 template <index_t DIM = 3> auto points() const {
591 typedef vecng<DIM,double> vecn;
592 return transform_range_ref(
593 index_range(0, nb()),
594 [this](index_t v)->const vecn& {
595 // for MSVC that cannot chose among const/non-const versions
596 return *reinterpret_cast<const vecn*>(point_ptr(v));
597 // return point<DIM>(v); // MSVC does not understand this one
598 }
599 );
600 }
601
606 template <index_t DIM = 3> auto points() {
607 typedef vecng<DIM,double> vecn;
608 return transform_range_ref(
609 index_range(0, nb()),
610 [this](index_t v)->vecn& {
611 // for MSVC that cannot chose among const/non-const versions
612 return *reinterpret_cast<vecn*>(point_ptr(v));
613 // return point<DIM>(v); // MSVC does not understand this one
614 }
615 );
616 }
617
618#endif
619
620 protected:
621
623 bool keep_attributes, bool keep_memory = false
624 ) override;
625
626 void resize_store(index_t new_size) override;
627
628 void bind_point_attribute(index_t dim, bool single_precision=false);
629
630 void copy(const MeshVertices& rhs, bool copy_attributes=true) {
631 index_t dim = rhs.dimension();
632 if(point_fp32_.is_bound()) {
633 point_fp32_.destroy();
634 }
635 if(point_.is_bound()) {
636 point_.destroy();
637 }
638 MeshSubElementsStore::copy(rhs, copy_attributes);
639 if(rhs.single_precision()) {
640 point_fp32_.bind_if_is_defined(attributes(),"point_fp32");
641 if(!point_fp32_.is_bound()) {
642 point_fp32_.create_vector_attribute(
643 attributes(), "point_fp32", dim
644 );
645 }
646 } else {
647 point_.bind_if_is_defined(attributes(),"point");
648 if(!point_.is_bound()) {
649 point_.create_vector_attribute(
650 attributes(), "point", dim
651 );
652 }
653 }
654 // Even if we do not copy the attributes, we need at least
655 // to copy the coordinates of the points !!
656 if(!copy_attributes) {
657 if(rhs.single_precision()) {
658 Memory::copy(
659 single_precision_point_ptr(0),
661 rhs.dimension()*rhs.nb()*sizeof(float)
662 );
663 } else {
664 Memory::copy(
665 point_ptr(0),
666 rhs.point_ptr(0),
667 rhs.dimension()*rhs.nb()*sizeof(double)
668 );
669 }
670 }
671 }
672
673 MeshEdges& edges_;
674 MeshFacetCornersStore& facet_corners_;
675 MeshCellCornersStore& cell_corners_;
676 Attribute<double> point_;
677 Attribute<float> point_fp32_;
678
679 friend class Mesh;
680 friend class GeogramIOHandler;
681 };
682
683 /*************************************************************************/
684
689 class GEOGRAM_API MeshEdges :
690 public MeshSubElementsStore, public MeshElements {
691 public:
692 MeshEdges(Mesh& mesh);
693 ~MeshEdges() override;
694
702 geo_debug_assert(e < nb());
703 geo_debug_assert(lv < 2);
704 return edge_vertex_[2*e+lv];
705 }
706
714 geo_debug_assert(e < nb());
715 geo_debug_assert(lv < 2);
716 edge_vertex_[2*e+lv] = v;
717 }
718
719
727 geo_debug_assert(c < 2*nb());
728 return &(edge_vertex_[c]);
729 }
730
738 geo_debug_assert(c < 2*nb());
739 return &(edge_vertex_[c]);
740 }
741
747 return create_sub_element();
748 }
749
756 return create_sub_elements(nb);
757 }
758
765 index_t result = create_edge();
766 set_vertex(result,0,v1);
767 set_vertex(result,1,v2);
768 return result;
769 }
770
772 vector<index_t>& to_delete, bool remove_isolated_vertices=true
773 ) override;
774
775 void permute_elements(vector<index_t>& permutation) override;
776
777 void clear(
778 bool keep_attributes=true, bool keep_memory=false
779 ) override;
780
781 void pop() override;
782
783 protected:
785 bool keep_attributes, bool keep_memory = false
786 ) override;
787
788 void resize_store(index_t new_size) override;
789
790 index_t create_sub_element() {
791 edge_vertex_.push_back(NO_VERTEX);
792 edge_vertex_.push_back(NO_VERTEX);
793 return MeshSubElementsStore::create_sub_element();
794 }
795
796 index_t create_sub_elements(index_t nb_in) {
797 edge_vertex_.resize(2*(nb()+nb_in),NO_VERTEX);
798 return MeshSubElementsStore::create_sub_elements(nb_in);
799 }
800
801 void copy(const MeshEdges& rhs, bool copy_attributes=true) {
802 MeshSubElementsStore::copy(rhs, copy_attributes);
803 edge_vertex_ = rhs.edge_vertex_;
804 }
805
806 vector<index_t> edge_vertex_;
807 friend class Mesh;
808 friend class GeogramIOHandler;
809 };
810
811 /**************************************************************************/
812
817 class GEOGRAM_API MeshFacetsStore : public MeshSubElementsStore {
818 public:
819 MeshFacetsStore(Mesh& mesh);
820
828 geo_debug_assert(f < nb());
829 return (is_simplicial_ ? 3*f : facet_ptr_[f]);
830 }
831
839 geo_debug_assert(f < nb());
840 return (is_simplicial_ ? 3*(f+1): facet_ptr_[f+1]);
841 }
842
849 geo_debug_assert(f < nb());
850 return (is_simplicial_ ? 3 : facet_ptr_[f+1] - facet_ptr_[f]);
851 }
852
861 geo_debug_assert(f < nb());
862 geo_debug_assert(lv < nb_corners(f));
863 return corners_begin(f)+lv;
864 }
865
873 bool are_simplices() const {
874 return is_simplicial_;
875 }
876
884 geo_debug_assert(!is_simplicial_);
885 geo_debug_assert(f < nb());
886 return &facet_ptr_[f];
887 }
888
889 protected:
891 bool keep_attributes, bool keep_memory = false
892 ) override;
893
894 void resize_store(index_t new_size) override;
895
896 index_t create_sub_element() {
897 if(!is_simplicial_) {
898 facet_ptr_.push_back(NO_CORNER);
899 }
900 return MeshSubElementsStore::create_sub_element();
901 }
902
903 index_t create_sub_elements(index_t nb) {
904 if(!is_simplicial_) {
905 for(index_t i=0; i<nb; ++i) {
906 facet_ptr_.push_back(NO_CORNER);
907 }
908 }
909 return MeshSubElementsStore::create_sub_elements(nb);
910 }
911
912 void copy(const MeshFacetsStore& rhs, bool copy_attributes=true) {
913 MeshSubElementsStore::copy(rhs,copy_attributes);
914 is_simplicial_ = rhs.is_simplicial_;
915 facet_ptr_ = rhs.facet_ptr_;
916 }
917
918 protected:
919 bool is_simplicial_;
920 vector<index_t> facet_ptr_;
921 friend class Mesh;
922 friend class GeogramIOHandler;
923 };
924
925 /*************************************************************************/
926
931 class GEOGRAM_API MeshFacetCornersStore : public MeshSubElementsStore {
932 public:
934
941 geo_assert(c < nb());
942 return corner_vertex_[c];
943 }
944
952 geo_assert(c < nb());
953 return corner_adjacent_facet_[c];
954 }
955
964 geo_assert(c < nb());
965 return &corner_adjacent_facet_[c];
966 }
967
968
977 geo_assert(c < nb());
978 return &corner_adjacent_facet_[c];
979 }
980
988 geo_debug_assert(c < nb());
989 geo_debug_assert(v < vertices_.nb());
990 corner_vertex_[c] = v;
991 }
992
1004 geo_debug_assert(c < nb());
1005 corner_vertex_[c] = v;
1006 }
1007
1015 geo_debug_assert(c < nb());
1016 geo_debug_assert(f == NO_FACET || f < facets_.nb());
1017 corner_adjacent_facet_[c] = f;
1018 }
1019
1028 geo_debug_assert(c < nb());
1029 return &(corner_vertex_[c]);
1030 }
1031
1040 geo_debug_assert(c < nb());
1041 return &(corner_vertex_[c]);
1042 }
1043
1050 template <index_t DIM=3> vecng<DIM,double>& point(index_t c) {
1051 geo_debug_assert(c < nb());
1052 return vertices_.point<DIM>(vertex(c));
1053 }
1054
1062 template <index_t DIM=3> const vecng<DIM,double>& point(
1063 index_t c
1064 ) const {
1065 geo_debug_assert(c < nb());
1066 return vertices_.point(vertex(c));
1067 }
1068
1069 protected:
1071 bool keep_attributes, bool keep_memory = false
1072 ) override;
1073
1074 void resize_store(index_t new_size) override;
1075
1076 index_t create_sub_element(index_t v, index_t f = NO_FACET) {
1077 corner_vertex_.push_back(v);
1078 corner_adjacent_facet_.push_back(f);
1079 return MeshSubElementsStore::create_sub_element();
1080 }
1081
1082 index_t create_sub_elements(index_t nb) {
1083 for(index_t i=0; i<nb; ++i) {
1084 corner_vertex_.push_back(NO_VERTEX);
1085 }
1086 for(index_t i=0; i<nb; ++i) {
1087 corner_adjacent_facet_.push_back(NO_FACET);
1088 }
1089 return MeshSubElementsStore::create_sub_elements(nb);
1090 }
1091
1092 void copy(
1093 const MeshFacetCornersStore& rhs, bool copy_attributes=true
1094 ) {
1095 MeshSubElementsStore::copy(rhs, copy_attributes);
1096 corner_vertex_ = rhs.corner_vertex_;
1097 corner_adjacent_facet_ = rhs.corner_adjacent_facet_;
1098 }
1099
1100 protected:
1101 MeshVertices& vertices_;
1102 MeshFacetsStore& facets_;
1103 vector<index_t> corner_vertex_;
1104 vector<index_t> corner_adjacent_facet_;
1105
1106 friend class MeshFacets;
1107 friend class Mesh;
1108 friend class GeogramIOHandler;
1109 };
1110
1111 /*************************************************************************/
1112
1117 class GEOGRAM_API MeshFacets : public MeshFacetsStore, public MeshElements {
1118 public:
1119
1126
1133 return nb_corners(f);
1134 }
1135
1144 return facet_corners_.vertex(corner(f,lv));
1145 }
1146
1147
1156 template <index_t DIM=3> const vecng<DIM,double>& point(
1157 index_t f, index_t lv
1158 ) const {
1159 return vertices_.point<DIM>(vertex(f,lv));
1160 }
1161
1170 template <index_t DIM=3> vecng<DIM,double>& point(
1171 index_t f, index_t lv
1172 ) {
1173 return vertices_.point<DIM>(vertex(f,lv));
1174 }
1175
1184 facet_corners_.set_vertex(corner(f,lv),v);
1185 }
1186
1195 for(index_t lv=0; lv<nb_vertices(f); ++lv) {
1196 if(vertex(f,lv) == v) {
1197 return lv;
1198 }
1199 }
1200 return NO_VERTEX;
1201 }
1202
1210 for(index_t lv=0; lv<nb_vertices(f1); ++lv) {
1211 index_t v = vertex(f1,lv);
1212 if(find_vertex(f2,v) != NO_VERTEX) {
1213 return lv;
1214 }
1215 }
1216 return NO_VERTEX;
1217 }
1218
1227 return facet_corners_.adjacent_facet(corner(f,le));
1228 }
1229
1238 for(index_t le=0; le<nb_vertices(f); ++le) {
1239 if(adjacent(f,le) == f2) {
1240 return le;
1241 }
1242 }
1243 return NO_INDEX;
1244 }
1245
1254 facet_corners_.set_adjacent_facet(corner(f,le),f2);
1255 }
1256
1265 geo_debug_assert(f < nb());
1266 geo_debug_assert(c >= corners_begin(f) && c < corners_end(f));
1267 return c + 1 == corners_end(f) ? corners_begin(f) : c + 1;
1268 }
1269
1278 geo_debug_assert(f < nb());
1279 geo_debug_assert(c >= corners_begin(f) && c < corners_end(f));
1280 return c == corners_begin(f) ? corners_end(f) - 1 : c - 1;
1281 }
1282
1291 for(index_t c1 = corners_begin(f); c1 != corners_end(f); ++c1) {
1292 index_t c2 = next_corner_around_facet(f,c1);
1293 if(
1294 facet_corners_.vertex(c1) == v1 &&
1295 facet_corners_.vertex(c2) == v2
1296 ) {
1297 return c1 - corners_begin(f);
1298 }
1299 }
1300 return NO_INDEX;
1301 }
1302
1304 vector<index_t>& to_delete,
1305 bool remove_isolated_vertices=true
1306 ) override;
1307
1308 void permute_elements(vector<index_t>& permutation) override;
1309
1310 void clear(
1311 bool keep_attributes=true, bool keep_memory=false
1312 ) override;
1313
1322 index_t nb_facets, index_t nb_vertices_per_polygon
1323 ) {
1324 if(nb_vertices_per_polygon != 3) {
1325 is_not_simplicial();
1326 }
1327
1328 index_t first_facet = nb();
1329 index_t co = facet_corners_.nb();
1330 facet_corners_.create_sub_elements(
1331 nb_facets*nb_vertices_per_polygon
1332 );
1333 index_t result = create_sub_elements(nb_facets);
1334
1335 if(!is_simplicial_) {
1336 for(index_t f=first_facet; f<=first_facet+nb_facets; ++f) {
1337 facet_ptr_[f] = co;
1338 co += nb_vertices_per_polygon;
1339 }
1340 geo_debug_assert(facet_ptr_.size() == nb()+1);
1341 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1342 }
1343 return result;
1344 }
1345
1351 void reserve(index_t nb_to_reserve) {
1352 facet_corners_.reserve_store(nb_to_reserve*3);
1353 this->reserve_store(nb_to_reserve);
1354 }
1355
1362 return create_facets(nb_triangles, 3);
1363 }
1364
1371 return create_facets(nb_quads, 4);
1372 }
1373
1380 geo_debug_assert(v1 != v2);
1381 geo_debug_assert(v2 != v3);
1382 geo_debug_assert(v3 != v1);
1383 facet_corners_.create_sub_element(v1);
1384 facet_corners_.create_sub_element(v2);
1385 facet_corners_.create_sub_element(v3);
1386 index_t result = create_sub_element();
1387 if(!is_simplicial_) {
1388 facet_ptr_[result+1] = facet_corners_.nb();
1389 geo_debug_assert(facet_ptr_.size() == nb()+1);
1390 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1391 }
1392 return result;
1393 }
1394
1401 is_not_simplicial();
1402 facet_corners_.create_sub_element(v1);
1403 facet_corners_.create_sub_element(v2);
1404 facet_corners_.create_sub_element(v3);
1405 facet_corners_.create_sub_element(v4);
1406 index_t result = create_sub_element();
1407 facet_ptr_[result+1] = facet_corners_.nb();
1408 geo_debug_assert(facet_ptr_.size() == nb()+1);
1409 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1410 return result;
1411 }
1412
1419 if(nb_vertices != 3) {
1420 is_not_simplicial();
1421 }
1422 for(index_t i=0; i<nb_vertices; ++i) {
1423 facet_corners_.create_sub_element(NO_VERTEX);
1424 }
1425 index_t result = create_sub_element();
1426 if(!is_simplicial_) {
1427 facet_ptr_[result+1] = facet_corners_.nb();
1428 geo_debug_assert(facet_ptr_.size() == nb()+1);
1429 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1430 }
1431 return result;
1432 }
1433
1440 index_t create_polygon(index_t nb_vertices, const index_t* vertices) {
1441 if(nb_vertices != 3) {
1442 is_not_simplicial();
1443 }
1444 for(index_t i=0; i<nb_vertices; ++i) {
1445 facet_corners_.create_sub_element(vertices[i]);
1446 }
1447 index_t result = create_sub_element();
1448 if(!is_simplicial_) {
1449 facet_ptr_[result+1] = facet_corners_.nb();
1450 geo_debug_assert(facet_ptr_.size() == nb()+1);
1451 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1452 }
1453 return result;
1454 }
1455
1463 return create_polygon(vertices.size(), vertices.data());
1464 }
1465
1470 void connect();
1471
1478 void connect(index_t facets_begin, index_t facets_end);
1479
1485
1491 void flip(index_t f);
1492
1498
1511 coord_index_t dim,
1512 vector<double>& vertices,
1513 vector<index_t>& triangles,
1514 bool steal_args
1515 );
1516
1517 /*
1518 * \brief Copies a triangle mesh into this Mesh.
1519 * \details Facet adjacence are not computed.
1520 * Facet and corner attributes are zeroed.
1521 * \param[in] triangles facet to vertex links
1522 * \param[in] steal_args if set, vertices and triangles
1523 * are 'stolen' from the arguments
1524 * (using vector::swap).
1525 */
1526 void assign_triangle_mesh(
1527 vector<index_t>& triangles,
1528 bool steal_args
1529 );
1530
1531 void pop() override;
1532
1539 geo_debug_assert(f < nb());
1540 return index_range(
1541 index_as_iterator(corners_begin(f)),
1542 index_as_iterator(corners_end(f))
1543 );
1544 }
1545
1546#ifndef MESH_NO_SYNTAXIC_SUGAR
1547
1553 auto vertices(index_t f) const {
1554 geo_debug_assert(f < nb());
1555 return transform_range(
1556 corners(f), [this](index_t c)->index_t {
1557 return facet_corners_.vertex(c);
1558 }
1559 );
1560 }
1561
1569 auto adjacent(index_t f) const {
1570 geo_debug_assert(f < nb());
1571 return transform_range(
1572 corners(f), [this](index_t c)->index_t {
1573 return facet_corners_.adjacent_facet(c);
1574 }
1575 );
1576 }
1577
1584 template <index_t DIM=3> auto points(index_t f) const {
1585 geo_debug_assert(f < nb());
1586 typedef vecng<DIM,double> vecn;
1587 return transform_range_ref(
1588 corners(f), [this](index_t c)->const vecn& {
1589 index_t v = facet_corners_.vertex(c);
1590 return vertices_.point<DIM>(v);
1591 }
1592 );
1593 }
1594
1601 template <index_t DIM=3> auto points(index_t f) {
1602 geo_debug_assert(f < nb());
1603 typedef vecng<DIM,double> vecn;
1604 return transform_range_ref(
1605 corners(f), [this](index_t c)->vecn& {
1606 index_t v = facet_corners_.vertex(c);
1607 return vertices_.point<DIM>(v);
1608 }
1609 );
1610 }
1611
1618 auto triangles(index_t f) const {
1619 geo_debug_assert(f < nb());
1620 index_t v0 = facet_corners_.vertex(corners_begin(f));
1621 return transform_range(
1623 index_as_iterator(corners_begin(f)+1),
1624 index_as_iterator(corners_end(f)-1)
1625 ),
1626 [this,v0](index_t c)->std::tuple<index_t, index_t, index_t> {
1627 return std::make_tuple(
1628 v0,
1629 facet_corners_.vertex(c),
1630 facet_corners_.vertex(c+1)
1631 );
1632 }
1633 );
1634 }
1635
1644 template <index_t DIM=3> auto triangle_points(index_t f) const {
1645 geo_debug_assert(f < nb());
1646 typedef vecng<DIM,double> vecn;
1647 return transform_range(
1648 triangles(f),
1649 [this](std::tuple<index_t, index_t, index_t> T)
1650 ->std::tuple<const vecn&, const vecn&, const vecn&> {
1651 return std::tuple<const vecn&, const vecn&, const vecn&>(
1652 vertices_.point<DIM>(std::get<0>(T)),
1653 vertices_.point<DIM>(std::get<1>(T)),
1654 vertices_.point<DIM>(std::get<2>(T))
1655 );
1656 }
1657 );
1658 }
1659
1668 template <index_t DIM=3> auto triangle_points(index_t f) {
1669 geo_debug_assert(f < nb());
1670 typedef vecng<DIM,double> vecn;
1671 return transform_range(
1672 triangles(f),
1673 [this](std::tuple<index_t, index_t, index_t> T)
1674 ->std::tuple<vecn&, vecn&, vecn&> {
1675 return std::tuple<vecn&, vecn&, vecn&>(
1676 vertices_.point(std::get<0>(T)),
1677 vertices_.point(std::get<1>(T)),
1678 vertices_.point(std::get<2>(T))
1679 );
1680 }
1681 );
1682 }
1683
1684#endif
1685
1686 protected:
1687
1692 if(!is_simplicial_) {
1693 is_simplicial_ = true;
1694 facet_ptr_.resize(1);
1695 facet_ptr_[0] = 0;
1696 }
1697 }
1698
1706 if(is_simplicial_) {
1707 is_simplicial_ = false;
1708 facet_ptr_.resize(nb()+1);
1709 for(index_t f=0; f<facet_ptr_.size(); ++f) {
1710 facet_ptr_[f] = 3*f;
1711 }
1712 }
1713 }
1714
1715 protected:
1716 MeshVertices& vertices_;
1717 MeshFacetCornersStore& facet_corners_;
1718 friend class Mesh;
1719 friend class GeogramIOHandler;
1720 friend void GEOGRAM_API tessellate_facets(
1721 Mesh& M, index_t max_nb_vertices
1722 );
1723 };
1724
1725 /*************************************************************************/
1726
1727 enum MeshCellType {
1728 MESH_TET = 0,
1729 MESH_HEX = 1,
1730 MESH_PRISM = 2,
1731 MESH_PYRAMID = 3,
1732 MESH_CONNECTOR = 4,
1733 MESH_NB_CELL_TYPES = 5
1734 };
1735
1770
1771
1778 namespace MeshCellDescriptors {
1782 GEOGRAM_API extern CellDescriptor*
1783 cell_type_to_cell_descriptor[GEO::MESH_NB_CELL_TYPES];
1784
1785 GEOGRAM_API extern CellDescriptor tet_descriptor;
1786 GEOGRAM_API extern CellDescriptor hex_descriptor;
1787 GEOGRAM_API extern CellDescriptor prism_descriptor;
1788 GEOGRAM_API extern CellDescriptor pyramid_descriptor;
1789 GEOGRAM_API extern CellDescriptor connector_descriptor;
1790 }
1791
1796 class GEOGRAM_API MeshCellsStore : public MeshSubElementsStore {
1797 public:
1798 MeshCellsStore(Mesh& mesh);
1799
1807 bool are_simplices() const {
1808 return is_simplicial_;
1809 }
1810
1817 MeshCellType type(index_t c) const {
1818 geo_debug_assert(c < nb());
1819 return is_simplicial_ ? MESH_TET : MeshCellType(cell_type_[c]);
1820 }
1821
1831 geo_debug_assert(c < nb());
1832 return is_simplicial_ ? MeshCellDescriptors::tet_descriptor :
1833 *(
1834 MeshCellDescriptors::cell_type_to_cell_descriptor[
1835 cell_type_[c]
1836 ]
1837 );
1838 }
1839
1850 MeshCellType t
1851 ) {
1852 geo_debug_assert(t < GEO::MESH_NB_CELL_TYPES);
1853 return *(MeshCellDescriptors::cell_type_to_cell_descriptor[t]);
1854 }
1855
1862 geo_debug_assert(c < nb());
1863 return descriptor(c).nb_vertices;
1864 }
1865
1873 geo_debug_assert(c < nb());
1874 return is_simplicial_ ? 4*c : cell_ptr_[c];
1875 }
1876
1884 geo_debug_assert(c < nb());
1885 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_corners(c);
1886 }
1887
1895 geo_debug_assert(c < nb());
1896 // There seems to be a linkage problem under MSVC for the
1897 // following assertion check...
1898#ifndef GEO_OS_WINDOWS
1899 geo_debug_assert(lv < nb_corners(c));
1900#endif
1901 return corners_begin(c) + lv;
1902 }
1903
1910 geo_debug_assert(c < nb());
1911 return descriptor(c).nb_facets;
1912 }
1913
1921 geo_debug_assert(c < nb());
1922 return is_simplicial_ ? 4*c : cell_ptr_[c];
1923 }
1924
1932 geo_debug_assert(c < nb());
1933 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_facets(c);
1934 }
1935
1943 geo_debug_assert(c < nb());
1944 geo_debug_assert(lf < nb_facets(c));
1945 return facets_begin(c) + lf;
1946 }
1947
1954 return descriptor(c).nb_edges;
1955 }
1956
1957 protected:
1959 bool keep_attributes, bool keep_memory = false
1960 ) override;
1961
1962 void resize_store(index_t new_size) override;
1963
1964 index_t create_sub_element(MeshCellType type) {
1965 if(!is_simplicial_) {
1966 cell_ptr_.push_back(NO_CORNER);
1967 cell_type_.push_back(Numeric::uint8(type));
1968 }
1969 return MeshSubElementsStore::create_sub_element();
1970 }
1971
1972 index_t create_sub_elements(index_t nb, MeshCellType type) {
1973 if(!is_simplicial_) {
1974 for(index_t i=0; i<nb; ++i) {
1975 cell_ptr_.push_back(NO_CORNER);
1976 cell_type_.push_back(Numeric::uint8(type));
1977 }
1978 }
1979 return MeshSubElementsStore::create_sub_elements(nb);
1980 }
1981
1982 void copy(
1983 const MeshCellsStore& rhs, bool copy_attributes=true
1984 ) {
1985 MeshSubElementsStore::copy(rhs, copy_attributes);
1986 is_simplicial_ = rhs.is_simplicial_;
1987 cell_type_ = rhs.cell_type_;
1988 cell_ptr_ = rhs.cell_ptr_;
1989 }
1990
1991 protected:
1992 bool is_simplicial_;
1993 vector<Numeric::uint8> cell_type_;
1994 vector<index_t> cell_ptr_;
1995
1996 protected:
1997 friend class Mesh;
1998 friend class GeogramIOHandler;
1999 };
2000
2001 /*************************************************************************/
2002
2007 class GEOGRAM_API MeshCellCornersStore : public MeshSubElementsStore {
2008 public:
2010
2017 geo_assert(c < nb());
2018 return corner_vertex_[c];
2019 }
2020
2027 geo_debug_assert(c < nb());
2028 geo_debug_assert(v < vertices_.nb());
2029 corner_vertex_[c] = v;
2030 }
2031
2040 geo_debug_assert(c < nb());
2041 return &(corner_vertex_[c]);
2042 }
2043
2052 geo_debug_assert(c < nb());
2053 return &(corner_vertex_[c]);
2054 }
2055
2062 template <index_t DIM=3> vecng<DIM,double>& point(index_t c) {
2063 geo_debug_assert(c < nb());
2064 return vertices_.point<DIM>(vertex(c));
2065 }
2066
2074 template <index_t DIM=3> const vecng<DIM,double>& point(
2075 index_t c
2076 ) const {
2077 geo_debug_assert(c < nb());
2078 return vertices_.point(vertex(c));
2079 }
2080
2081 protected:
2083 bool keep_attributes, bool keep_memory = false
2084 ) override;
2085
2086 void resize_store(index_t new_size) override;
2087
2088 index_t create_sub_element(index_t v) {
2089 corner_vertex_.push_back(v);
2090 return MeshSubElementsStore::create_sub_element();
2091 }
2092
2093 index_t create_sub_elements(index_t nb) {
2094 for(index_t i=0; i<nb; ++i) {
2095 corner_vertex_.push_back(NO_VERTEX);
2096 }
2097 return MeshSubElementsStore::create_sub_elements(nb);
2098 }
2099
2100 void copy(
2101 const MeshCellCornersStore& rhs, bool copy_attributes=true
2102 ) {
2103 MeshSubElementsStore::copy(rhs, copy_attributes);
2104 corner_vertex_ = rhs.corner_vertex_;
2105 }
2106
2107 protected:
2108 MeshVertices& vertices_;
2109 vector<index_t> corner_vertex_;
2110
2111 friend class MeshCells;
2112 friend class Mesh;
2113 friend class GeogramIOHandler;
2114 };
2115
2116 /*************************************************************************/
2117
2122 class GEOGRAM_API MeshCellFacetsStore : public MeshSubElementsStore {
2123 public:
2129
2137 geo_assert(f < nb());
2138 return adjacent_cell_[f];
2139 }
2140
2149 geo_debug_assert(f < nb());
2150 geo_debug_assert(c == NO_CELL || c < cells_.nb());
2151 adjacent_cell_[f] = c;
2152 }
2153
2161 geo_assert(f < nb());
2162 return &adjacent_cell_[f];
2163 }
2164
2172 geo_assert(f < nb());
2173 return &adjacent_cell_[f];
2174 }
2175
2176 protected:
2178 bool keep_attributes, bool keep_memory = false
2179 ) override;
2180
2181 void resize_store(index_t new_size) override;
2182
2183 index_t create_sub_element(index_t c = NO_CELL) {
2184 adjacent_cell_.push_back(c);
2185 return MeshSubElementsStore::create_sub_element();
2186 }
2187
2188 index_t create_sub_elements(index_t nb) {
2189 for(index_t i=0; i<nb; ++i) {
2190 adjacent_cell_.push_back(NO_CELL);
2191 }
2192 return MeshSubElementsStore::create_sub_elements(nb);
2193 }
2194
2195 void copy(
2196 const MeshCellFacetsStore& rhs, bool copy_attributes=true
2197 ) {
2198 MeshSubElementsStore::copy(rhs, copy_attributes);
2199 adjacent_cell_ = rhs.adjacent_cell_;
2200 }
2201
2202 protected:
2203 MeshVertices& vertices_;
2204 MeshCellsStore& cells_;
2205 vector<index_t> adjacent_cell_;
2206
2207 friend class MeshCells;
2208 friend class Mesh;
2209 friend class GeogramIOHandler;
2210 };
2211
2212 /*************************************************************************/
2213
2218 class GEOGRAM_API MeshCells : public MeshCellsStore, public MeshElements {
2219 public:
2225
2232 return nb_corners(c);
2233 }
2234
2242 return cell_corners_.vertex(corner(c,lv));
2243 }
2244
2252 cell_corners_.set_vertex(corner(c,lv),v);
2253 }
2254
2263 template <index_t DIM=3> const vecng<DIM,double>& point(
2264 index_t c, index_t lv
2265 ) const {
2266 return vertices_.point<DIM>(vertex(c,lv));
2267 }
2268
2277 template <index_t DIM=3> vecng<DIM,double>& point(
2278 index_t c, index_t lv
2279 ) {
2280 return vertices_.point<DIM>(vertex(c,lv));
2281 }
2282
2291 return cell_facets_.adjacent_cell(facet(c,lf));
2292 }
2293
2302 cell_facets_.set_adjacent_cell(facet(c,lf),c2);
2303 }
2304
2312 geo_debug_assert(lf < nb_facets(c));
2313 return descriptor(c).nb_vertices_in_facet[lf];
2314 }
2315
2325 geo_debug_assert(lv < facet_nb_vertices(c, lf));
2326 return cell_corners_.vertex(
2327 corner(c, descriptor(c).facet_vertex[lf][lv])
2328 );
2329 }
2339 geo_debug_assert(lc < facet_nb_vertices(c, lf));
2340 return corner(c, descriptor(c).facet_vertex[lf][lc]);
2341 }
2342
2352 geo_debug_assert(le < nb_edges(c));
2353 geo_debug_assert(lv < 2);
2354 return cell_corners_.vertex(
2355 corner(c,descriptor(c).edge_vertex[le][lv])
2356 );
2357 }
2358
2370 geo_debug_assert(le < nb_edges(c));
2371 geo_debug_assert(lf < 2);
2372 return descriptor(c).edge_adjacent_facet[le][lf];
2373 }
2374
2381 geo_debug_assert(c < nb());
2382 return index_range(
2383 index_as_iterator(corners_begin(c)),
2384 index_as_iterator(corners_end(c))
2385 );
2386 }
2387
2388#ifndef MESH_NO_SYNTAXIC_SUGAR
2389
2396 template <index_t DIM=3> auto points(index_t cell) const {
2397 geo_debug_assert(cell < nb());
2398 typedef vecng<DIM,double> vecn;
2399 return transform_range_ref(
2400 corners(cell), [this](index_t c)->const vecn& {
2401 index_t v = cell_corners_.vertex(c);
2402 return vertices_.point<DIM>(v);
2403 }
2404 );
2405 }
2406
2413 template <index_t DIM=3> auto points(index_t cell) {
2414 geo_debug_assert(cell < nb());
2415 typedef vecng<DIM,double> vecn;
2416 return transform_range_ref(
2417 corners(cell), [this](index_t c)->vecn& {
2418 index_t v = cell_corners_.vertex(c);
2419 return vertices_.point<DIM>(v);
2420 }
2421 );
2422 }
2423
2424#endif
2425
2426 void clear(
2427 bool keep_attributes=true, bool keep_memory=false
2428 ) override;
2429
2431 vector<index_t>& to_delete,
2432 bool remove_isolated_vertices=true
2433 ) override;
2434
2435 void permute_elements(vector<index_t>& permutation) override;
2436
2445 index_t create_cells(index_t nb_cells, MeshCellType type) {
2446
2447 if(nb_cells == 0) {
2448 return NO_CELL;
2449 }
2450
2451
2452 if(type != MESH_TET) {
2453 is_not_simplicial();
2454 }
2455
2456 const CellDescriptor& desc = cell_type_to_cell_descriptor(type);
2457
2458 // Note: there is padding, the same number of corners and
2459 // faces is created for each cell, so that a single cell
2460 // pointer is used for both.
2461
2462 index_t cell_size = std::max(desc.nb_vertices, desc.nb_facets);
2463 index_t first_cell = nb();
2464 index_t co = cell_corners_.nb();
2465
2466 cell_corners_.create_sub_elements(
2467 nb_cells*cell_size
2468 );
2469
2470 cell_facets_.create_sub_elements(
2471 nb_cells*cell_size
2472 );
2473
2474 index_t result = create_sub_elements(nb_cells, type);
2475
2476 if(!is_simplicial_) {
2477 for(index_t c=first_cell; c<=first_cell+nb_cells; ++c) {
2478 cell_ptr_[c] = co;
2479 co += cell_size;
2480 }
2481
2482 geo_debug_assert(cell_ptr_.size() == nb()+1);
2483 geo_debug_assert(cell_ptr_[nb()] == cell_corners_.nb());
2484 geo_debug_assert(cell_ptr_[nb()] == cell_facets_.nb());
2485 }
2486
2487 return result;
2488 }
2489
2496 return create_cells(nb_tets, MESH_TET);
2497 }
2498
2505 return create_cells(nb_hexes, MESH_HEX);
2506 }
2507
2514 return create_cells(nb_prisms, MESH_PRISM);
2515 }
2516
2523 return create_cells(nb_pyramids, MESH_PYRAMID);
2524 }
2525
2535 index_t v1, index_t v2, index_t v3, index_t v4,
2536 index_t adj1 = NO_CELL,
2537 index_t adj2 = NO_CELL,
2538 index_t adj3 = NO_CELL,
2539 index_t adj4 = NO_CELL
2540 ) {
2541 cell_corners_.create_sub_element(v1);
2542 cell_corners_.create_sub_element(v2);
2543 cell_corners_.create_sub_element(v3);
2544 cell_corners_.create_sub_element(v4);
2545 cell_facets_.create_sub_element(adj1);
2546 cell_facets_.create_sub_element(adj2);
2547 cell_facets_.create_sub_element(adj3);
2548 cell_facets_.create_sub_element(adj4);
2549 index_t result = create_sub_element(MESH_TET);
2550 if(!is_simplicial_) {
2551 cell_ptr_[nb()] = cell_corners_.nb();
2552 }
2553 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2554 return result;
2555 }
2556
2567 index_t v1, index_t v2, index_t v3, index_t v4,
2568 index_t v5, index_t v6, index_t v7, index_t v8,
2569 index_t adj1 = NO_CELL,
2570 index_t adj2 = NO_CELL,
2571 index_t adj3 = NO_CELL,
2572 index_t adj4 = NO_CELL,
2573 index_t adj5 = NO_CELL,
2574 index_t adj6 = NO_CELL
2575 ) {
2576 is_not_simplicial();
2577 cell_corners_.create_sub_element(v1);
2578 cell_corners_.create_sub_element(v2);
2579 cell_corners_.create_sub_element(v3);
2580 cell_corners_.create_sub_element(v4);
2581 cell_corners_.create_sub_element(v5);
2582 cell_corners_.create_sub_element(v6);
2583 cell_corners_.create_sub_element(v7);
2584 cell_corners_.create_sub_element(v8);
2585 cell_facets_.create_sub_element(adj1);
2586 cell_facets_.create_sub_element(adj2);
2587 cell_facets_.create_sub_element(adj3);
2588 cell_facets_.create_sub_element(adj4);
2589 cell_facets_.create_sub_element(adj5);
2590 cell_facets_.create_sub_element(adj6);
2591 cell_facets_.create_sub_element(NO_CELL); // padding
2592 cell_facets_.create_sub_element(NO_CELL); // padding
2593 index_t result = create_sub_element(MESH_HEX);
2594 cell_ptr_[nb()] = cell_corners_.nb();
2595 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2596 return result;
2597 }
2598
2609 index_t v1, index_t v2,
2610 index_t v3, index_t v4,
2611 index_t v5, index_t v6,
2612 index_t adj1 = NO_CELL,
2613 index_t adj2 = NO_CELL,
2614 index_t adj3 = NO_CELL,
2615 index_t adj4 = NO_CELL,
2616 index_t adj5 = NO_CELL
2617 ) {
2618 is_not_simplicial();
2619 cell_corners_.create_sub_element(v1);
2620 cell_corners_.create_sub_element(v2);
2621 cell_corners_.create_sub_element(v3);
2622 cell_corners_.create_sub_element(v4);
2623 cell_corners_.create_sub_element(v5);
2624 cell_corners_.create_sub_element(v6);
2625 cell_facets_.create_sub_element(adj1);
2626 cell_facets_.create_sub_element(adj2);
2627 cell_facets_.create_sub_element(adj3);
2628 cell_facets_.create_sub_element(adj4);
2629 cell_facets_.create_sub_element(adj5);
2630 cell_facets_.create_sub_element(NO_CELL); // padding
2631 index_t result = create_sub_element(MESH_PRISM);
2632 cell_ptr_[nb()] = cell_corners_.nb();
2633 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2634 return result;
2635 }
2636
2647 index_t v1, index_t v2, index_t v3, index_t v4, index_t v5,
2648 index_t adj1 = NO_CELL,
2649 index_t adj2 = NO_CELL,
2650 index_t adj3 = NO_CELL,
2651 index_t adj4 = NO_CELL,
2652 index_t adj5 = NO_CELL
2653 ) {
2654 is_not_simplicial();
2655 cell_corners_.create_sub_element(v1);
2656 cell_corners_.create_sub_element(v2);
2657 cell_corners_.create_sub_element(v3);
2658 cell_corners_.create_sub_element(v4);
2659 cell_corners_.create_sub_element(v5);
2660 cell_facets_.create_sub_element(adj1);
2661 cell_facets_.create_sub_element(adj2);
2662 cell_facets_.create_sub_element(adj3);
2663 cell_facets_.create_sub_element(adj4);
2664 cell_facets_.create_sub_element(adj5);
2665 index_t result = create_sub_element(MESH_PYRAMID);
2666 cell_ptr_[nb()] = cell_corners_.nb();
2667 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2668 return result;
2669 }
2670
2684 index_t v1, index_t v2, index_t v3, index_t v4,
2685 index_t adj1 = NO_CELL,
2686 index_t adj2 = NO_CELL,
2687 index_t adj3 = NO_CELL
2688 ) {
2689 is_not_simplicial();
2690 cell_corners_.create_sub_element(v1);
2691 cell_corners_.create_sub_element(v2);
2692 cell_corners_.create_sub_element(v3);
2693 cell_corners_.create_sub_element(v4);
2694 cell_facets_.create_sub_element(adj1);
2695 cell_facets_.create_sub_element(adj2);
2696 cell_facets_.create_sub_element(adj3);
2697 cell_facets_.create_sub_element(NO_CELL); // padding
2698 index_t result = create_sub_element(MESH_CONNECTOR);
2699 cell_ptr_[nb()] = cell_corners_.nb();
2700 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2701 return result;
2702 }
2703
2715 bool remove_trivial_slivers = true, bool verbose_if_OK=false
2716 );
2717
2723
2732
2744 coord_index_t dim,
2745 vector<double>& vertices,
2746 vector<index_t>& tets,
2747 bool steal_args
2748 );
2749
2759 vector<index_t>& tets,
2760 bool steal_args
2761 );
2762
2763 void pop() override;
2764
2765 index_t tet_adjacent(index_t t, index_t lf) const {
2766 geo_debug_assert(is_simplicial_);
2767 geo_debug_assert(t < nb());
2768 geo_debug_assert(lf < 4);
2769 return cell_facets_.adjacent_cell_[4*t+lf];
2770 }
2771
2772 index_t find_tet_adjacent(index_t t, index_t t2) const {
2773 geo_debug_assert(is_simplicial_);
2774 geo_debug_assert(t < nb());
2775 geo_debug_assert(t2 < nb());
2776 for(index_t lf=0; lf<4; ++lf) {
2777 if(cell_facets_.adjacent_cell_[4*t+lf] == t2) {
2778 return lf;
2779 }
2780 }
2781 return NO_FACET;
2782 }
2783
2784 index_t tet_vertex(index_t t, index_t lv) const {
2785 geo_debug_assert(is_simplicial_);
2786 geo_debug_assert(t < nb());
2787 geo_debug_assert(lv < 4);
2788 return cell_corners_.corner_vertex_[4*t+lv];
2789 }
2790
2791 index_t find_tet_vertex(index_t t, index_t v) const {
2792 geo_debug_assert(is_simplicial_);
2793 geo_debug_assert(t < nb());
2794 geo_debug_assert(v < vertices_.nb());
2795 for(index_t lv=0; lv<4; ++lv) {
2796 if(cell_corners_.corner_vertex_[4*t+lv] == v) {
2797 return lv;
2798 }
2799 }
2800 return NO_VERTEX;
2801 }
2802
2814 index_t t, index_t lf, index_t lv
2815 ) const {
2816 geo_debug_assert(is_simplicial_);
2817 geo_debug_assert(t < nb());
2818 geo_debug_assert(lf < 4);
2819 geo_debug_assert(lv < 3);
2820 return cell_corners_.vertex(
2821 4 * t + local_tet_facet_vertex_index(lf,lv)
2822 );
2823 }
2824
2839 index_t t, index_t v1, index_t v2, index_t v3
2840 ) const {
2841 geo_debug_assert(is_simplicial_);
2842 for(index_t lf = 0; lf < 4; ++lf) {
2843 index_t w1 = tet_facet_vertex(t, lf, 0);
2844 index_t w2 = tet_facet_vertex(t, lf, 1);
2845 index_t w3 = tet_facet_vertex(t, lf, 2);
2846 if(
2847 (v1 == w1 && v2 == w2 && v3 == w3) ||
2848 (v1 == w2 && v2 == w3 && v3 == w1) ||
2849 (v1 == w3 && v2 == w1 && v3 == w2)
2850 ) {
2851 return lf;
2852 }
2853 }
2854 return NO_FACET;
2855 }
2856
2866 geo_debug_assert(lf < 4);
2867 geo_debug_assert(lv < 3);
2868 return MeshCellDescriptors::tet_descriptor.facet_vertex[lf][lv];
2869 }
2870
2871 protected:
2872
2880 if(is_simplicial_) {
2881 is_simplicial_ = false;
2882 cell_ptr_.resize(nb()+1);
2883 cell_type_.assign(nb(), MESH_TET);
2884 for(index_t c=0; c<cell_ptr_.size(); ++c) {
2885 cell_ptr_[c] = 4*c;
2886 }
2887 }
2888 }
2889
2902 index_t c1, index_t f1, index_t c2, index_t f2
2903 ) const;
2904
2914 geo_debug_assert(c < nb());
2915 geo_debug_assert(v < vertices_.nb());
2916 for(index_t lv=0; lv<nb_vertices(c); ++lv) {
2917 if(vertex(c,lv) == v) {
2918 return lv;
2919 }
2920 }
2921 return NO_VERTEX;
2922 }
2923
2936 index_t c1, index_t c2, index_t f2
2937 ) const {
2938 for(index_t f1=0; f1<nb_facets(c1); ++f1) {
2939 if(facets_match(c1,f1,c2,f2)) {
2940 return f1;
2941 }
2942 }
2943 return NO_FACET;
2944 }
2945
2959 index_t c1, index_t lf1,
2960 index_t c2, index_t lf2
2961 ) const;
2962
2963
2978 index_t c1, index_t f1,
2979 index_t c2, index_t f2,
2980 index_t& e1, index_t& e2
2981 ) const;
2982
3002 index_t c1, index_t lf1,
3003 const std::vector< std::pair<index_t, index_t> >& matches
3004 );
3005
3011
3012 protected:
3013 MeshVertices& vertices_;
3014 MeshCellCornersStore& cell_corners_;
3015 MeshCellFacetsStore& cell_facets_;
3016 friend class Mesh;
3017 friend class GeogramIOHandler;
3018 };
3019
3020 /*************************************************************************/
3021
3030 MESH_NONE = 0,
3031 MESH_VERTICES = 1,
3032 MESH_FACETS = 2,
3033 MESH_EDGES = 4,
3034 MESH_CELLS = 8,
3035 MESH_ALL_ELEMENTS = 15,
3036 MESH_FACET_CORNERS = 16,
3037 MESH_CELL_CORNERS = 32,
3038 MESH_CELL_FACETS = 64,
3039 MESH_ALL_SUBELEMENTS = 65
3040 };
3041
3042 /*************************************************************************/
3043
3050 class GEOGRAM_API Mesh {
3051 public:
3052 MeshVertices vertices;
3053 MeshEdges edges;
3054 MeshFacets facets;
3055 MeshFacetCornersStore facet_corners;
3056 MeshCells cells;
3057 MeshCellCornersStore cell_corners;
3058 MeshCellFacetsStore cell_facets;
3059
3067 Mesh(index_t dimension=3, bool single_precision=false);
3068
3072 virtual ~Mesh();
3073
3084 void clear(bool keep_attributes=true, bool keep_memory=false);
3085
3089 void show_stats(const std::string& tag = "Mesh") const;
3090
3091
3100
3101
3114 void copy(
3115 const Mesh& rhs,
3116 bool copy_attributes=true,
3117 MeshElementsFlags what=MESH_ALL_ELEMENTS
3118 );
3119
3120
3125 std::string get_attributes() const;
3126
3133 std::string get_scalar_attributes() const;
3134
3141 std::string get_vector_attributes(index_t max_dim = 0) const;
3142
3148
3156
3164
3165
3173
3182 ) const;
3183
3191
3200 const std::string& name
3201 );
3202
3218 const std::string& full_attribute_name,
3219 MeshElementsFlags& where,
3220 std::string& attribute_name,
3221 index_t& component
3222 );
3223
3224 protected:
3233 const std::string& tag, const std::string& subelement_name,
3234 const MeshSubElementsStore& subelements
3235 ) const;
3236
3244 Mesh(const Mesh& rhs) = delete;
3245
3253 const Mesh& operator=(const Mesh& rhs) = delete;
3254 };
3255
3256 /*************************************************************************/
3257}
3258
3259#endif
#define geo_assert(x)
Verifies that a condition is met.
Definition assert.h:149
#define geo_debug_assert(x)
Verifies that a condition is met.
Definition assert.h:196
Generic mechanism for attributes.
Manages an attribute attached to a set of object.
Managers a set of attributes attached to an object.
Definition attributes.h:849
index_t size() const
Gets the size.
Definition attributes.h:884
Stores the cell corners of a mesh (low-level store)
Definition mesh.h:2007
void set_vertex(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:2026
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition mesh.h:2016
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
index_t * vertex_index_ptr(index_t c)
Gets a pointer to the vertex that a corner is incident to.
Definition mesh.h:2039
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
vecng< DIM, double > & point(index_t c)
Gets the point associated with a corner.
Definition mesh.h:2062
const index_t * vertex_index_ptr(index_t c) const
Gets a pointer to the vertex that a corner is incident to.
Definition mesh.h:2051
const vecng< DIM, double > & point(index_t c) const
Gets the point associated with a corner.
Definition mesh.h:2074
Stores the cell facets of a mesh (low-level store)
Definition mesh.h:2122
index_t adjacent_cell(index_t f) const
Gets a cell adjacent to a facet.
Definition mesh.h:2136
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
index_t * adjacent_cell_ptr(index_t f)
Gets a pointer to a cell adjacent to a facet.
Definition mesh.h:2171
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
const index_t * adjacent_cell_ptr(index_t f) const
Gets a const pointer to a cell adjacent to a facet.
Definition mesh.h:2160
MeshCellFacetsStore(Mesh &mesh)
MeshCellFacetsStore constructor.
void set_adjacent_cell(index_t f, index_t c)
Sets a cell adjacent to a facet.
Definition mesh.h:2148
Stores the cells of a mesh (low-level store)
Definition mesh.h:1796
index_t facet(index_t c, index_t lf) const
Gets a facet of a cell by local facet index.
Definition mesh.h:1942
bool are_simplices() const
Tests whether all the cells are tetrahedra.
Definition mesh.h:1807
static const CellDescriptor & cell_type_to_cell_descriptor(MeshCellType t)
Gets a descriptor by cell type.
Definition mesh.h:1849
const CellDescriptor & descriptor(index_t c) const
Gets the descriptor of a cell.
Definition mesh.h:1830
index_t corner(index_t c, index_t lv) const
Gets a corner of a cell by local vertex index.
Definition mesh.h:1894
index_t nb_facets(index_t c) const
Gets the number of facets of a cell.
Definition mesh.h:1909
index_t corners_end(index_t c) const
Gets the upper limit for iterating over the corners of a cell.
Definition mesh.h:1883
MeshCellType type(index_t c) const
Gets the type of a cell.
Definition mesh.h:1817
index_t facets_end(index_t c) const
Gets the upper limit for iterating over the facets of a cell.
Definition mesh.h:1931
index_t nb_corners(index_t c) const
Gets the number of corners of a cell.
Definition mesh.h:1861
index_t corners_begin(index_t c) const
Gets the first element for iterating over the corners of a cell.
Definition mesh.h:1872
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
index_t nb_edges(index_t c) const
Gets the number of edges in a cell.
Definition mesh.h:1953
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
index_t facets_begin(index_t c) const
Gets the first element for iterating over the facets of a cell.
Definition mesh.h:1920
The cells of a mesh.
Definition mesh.h:2218
index_t create_cells(index_t nb_cells, MeshCellType type)
Creates a contiguous chunk of cells of the same type.
Definition mesh.h:2445
void pop() override
Removes the last element.
void compute_borders()
Replaces the surfacic part of this mesh with the borders of the volumetric part.
void set_vertex(index_t c, index_t lv, index_t v)
Sets a vertex of a cell by local vertex index.
Definition mesh.h:2251
index_t create_pyramids(index_t nb_pyramids)
Creates a contiguous chunk of pyramids.
Definition mesh.h:2522
void assign_tet_mesh(vector< index_t > &tets, bool steal_args)
Copies a tetrahedron mesh into this Mesh.
index_t adjacent(index_t c, index_t lf) const
Gets a cell adjacent to another one by local facet index.
Definition mesh.h:2290
void assign_tet_mesh(coord_index_t dim, vector< double > &vertices, vector< index_t > &tets, bool steal_args)
Copies a tetrahedron mesh into this Mesh.
vecng< DIM, double > & point(index_t c, index_t lv)
Gets a point by cell and local vertex index.
Definition mesh.h:2277
bool triangular_facets_have_common_edge(index_t c1, index_t f1, index_t c2, index_t f2, index_t &e1, index_t &e2) const
Tests whether two triangular cell facets have a common edge.
bool facets_match(index_t c1, index_t f1, index_t c2, index_t f2) const
Tests whether two cell facets can be connected.
index_t create_connector(index_t v1, index_t v2, index_t v3, index_t v4, index_t adj1=NO_CELL, index_t adj2=NO_CELL, index_t adj3=NO_CELL)
Creates a connector.
Definition mesh.h:2683
index_t tet_facet_vertex(index_t t, index_t lf, index_t lv) const
Gets a vertex of a tetrahedron by local facet index and local vertex index in facet.
Definition mesh.h:2813
index_range corners(index_t c) const
Gets the corners of a cell.
Definition mesh.h:2380
auto points(index_t cell)
Gets the points associated with the vertices of a cell.
Definition mesh.h:2413
MeshCells(Mesh &mesh)
MeshCells constructor.
index_t edge_vertex(index_t c, index_t le, index_t lv) const
Gets a cell vertex by local edge index and local vertex index in the edge.
Definition mesh.h:2351
void connect(bool remove_trivial_slivers=true, bool verbose_if_OK=false)
Connects the cells.
static index_t local_tet_facet_vertex_index(index_t lf, index_t lv)
Gives the local index of a vertex in a tetrahedron from its facet and vertex local indices.
Definition mesh.h:2865
index_t create_prism(index_t v1, index_t v2, index_t v3, index_t v4, index_t v5, index_t v6, index_t adj1=NO_CELL, index_t adj2=NO_CELL, index_t adj3=NO_CELL, index_t adj4=NO_CELL, index_t adj5=NO_CELL)
Creates a prism.
Definition mesh.h:2608
index_t nb_vertices(index_t c) const
Gets the number of vertices of a cell.
Definition mesh.h:2231
index_t facet_vertex(index_t c, index_t lf, index_t lv) const
Gets a vertex of a cell by local facet index and local vertex index in the facet.
Definition mesh.h:2324
void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true) override
Deletes a set of elements.
index_t create_pyramid(index_t v1, index_t v2, index_t v3, index_t v4, index_t v5, index_t adj1=NO_CELL, index_t adj2=NO_CELL, index_t adj3=NO_CELL, index_t adj4=NO_CELL, index_t adj5=NO_CELL)
Creates a pyramid.
Definition mesh.h:2646
index_t find_tet_facet(index_t t, index_t v1, index_t v2, index_t v3) const
Finds the local index of a facet in a tetrahedron by the global indices of its vertices.
Definition mesh.h:2838
void permute_elements(vector< index_t > &permutation) override
Applies a permutation to the elements and their attributes.
void is_not_simplicial()
Indicates that the stored elements are no longer only tetrahedra.
Definition mesh.h:2879
index_t facet_corner(index_t c, index_t lf, index_t lc) const
Gets a corner of a cell by local facet index and local corner index in the facet.
Definition mesh.h:2338
index_t find_cell_vertex(index_t c, index_t v) const
Finds the local index of a vertex in a cell.
Definition mesh.h:2913
index_t create_hexes(index_t nb_hexes)
Creates a contiguous chunk of hexahedra.
Definition mesh.h:2504
index_t create_tets(index_t nb_tets)
Creates a contiguous chunk of tetrahedra.
Definition mesh.h:2495
index_t edge_adjacent_facet(index_t c, index_t le, index_t lf) const
Gets a cell local facet index by local edge index and local facet index in the edge.
Definition mesh.h:2369
void compute_borders(Attribute< index_t > &facet_cell)
Replaces the surfacic part of this mesh with the borders of the volumetric part.
bool create_connector(index_t c1, index_t lf1, const std::vector< std::pair< index_t, index_t > > &matches)
Creates a connector between a quadrandular facet and two triangular facets.
void set_adjacent(index_t c, index_t lf, index_t c2)
Sets a cell adjacent to another one by local facet index.
Definition mesh.h:2301
void clear(bool keep_attributes=true, bool keep_memory=false) override
Removes all the elements and attributes.
index_t create_prisms(index_t nb_prisms)
Creates a contiguous chunk of prisms.
Definition mesh.h:2513
index_t create_tet(index_t v1, index_t v2, index_t v3, index_t v4, index_t adj1=NO_CELL, index_t adj2=NO_CELL, index_t adj3=NO_CELL, index_t adj4=NO_CELL)
Creates a tetrahedron.
Definition mesh.h:2534
index_t create_hex(index_t v1, index_t v2, index_t v3, index_t v4, index_t v5, index_t v6, index_t v7, index_t v8, index_t adj1=NO_CELL, index_t adj2=NO_CELL, index_t adj3=NO_CELL, index_t adj4=NO_CELL, index_t adj5=NO_CELL, index_t adj6=NO_CELL)
Creates an hexahedron.
Definition mesh.h:2566
void connect_tets()
Optimized implementation of connect() used when the mesh is simplicial.
index_t facet_nb_vertices(index_t c, index_t lf) const
Gets the number of vertices in a cell facet.
Definition mesh.h:2311
bool triangular_facet_matches_quad_facet(index_t c1, index_t lf1, index_t c2, index_t lf2) const
Tests whether a triangular facet matches a quad facet.
auto points(index_t cell) const
Gets the points associated with the vertices of a cell.
Definition mesh.h:2396
index_t find_cell_facet(index_t c1, index_t c2, index_t f2) const
Finds the local index of a facet in a cell that can be connected to a facet of another cell.
Definition mesh.h:2935
const vecng< DIM, double > & point(index_t c, index_t lv) const
Gets a point by cell and local vertex index.
Definition mesh.h:2263
index_t vertex(index_t c, index_t lv) const
Gets a vertex of a cell by local vertex index.
Definition mesh.h:2241
The edges of a mesh.
Definition mesh.h:690
index_t vertex(index_t e, index_t lv) const
Gets the index of an edge vertex.
Definition mesh.h:701
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
void pop() override
Removes the last element.
const index_t * vertex_index_ptr(index_t c) const
Gets a pointer to a vertex index by corner index.
Definition mesh.h:737
void clear(bool keep_attributes=true, bool keep_memory=false) override
Removes all the elements and attributes.
index_t create_edge(index_t v1, index_t v2)
Creates a new edge.
Definition mesh.h:764
index_t create_edge()
Creates a new edge.
Definition mesh.h:746
void permute_elements(vector< index_t > &permutation) override
Applies a permutation to the elements and their attributes.
index_t create_edges(index_t nb)
Creates a batch of edges.
Definition mesh.h:755
index_t * vertex_index_ptr(index_t c)
Gets a pointer to a vertex index by corner index.
Definition mesh.h:726
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true) override
Deletes a set of elements.
void set_vertex(index_t e, index_t lv, index_t v)
Sets a vertex of an edge.
Definition mesh.h:713
Base class for mesh elements.
Definition mesh.h:252
virtual void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true)=0
Deletes a set of elements.
static bool has_non_zero(const GEO::vector< index_t > &I)
Tests whether a vector contains a non-zero value.
Definition mesh.h:311
virtual void clear(bool keep_attributes=true, bool keep_memory=false)=0
Removes all the elements and attributes.
virtual void pop()=0
Removes the last element.
virtual void permute_elements(vector< index_t > &permutation)=0
Applies a permutation to the elements and their attributes.
Stores the facet corners of a mesh (low-level store)
Definition mesh.h:931
index_t * vertex_index_ptr(index_t c)
Gets a pointer to the vertex that a corner is incident to.
Definition mesh.h:1027
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
const index_t * adjacent_facet_ptr(index_t c) const
Gets a pointer to the the facet index that a corner is adjacent to.
Definition mesh.h:963
vecng< DIM, double > & point(index_t c)
Gets the point associated with a corner.
Definition mesh.h:1050
index_t * adjacent_facet_ptr(index_t c)
Gets a pointer to the the facet index that a corner is adjacent to.
Definition mesh.h:976
index_t adjacent_facet(index_t c) const
Gets the facet that a corner is adjacent to.
Definition mesh.h:951
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
const index_t * vertex_index_ptr(index_t c) const
Gets a pointer to the vertex that a corner is incident to.
Definition mesh.h:1039
void set_vertex_no_check(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:1003
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition mesh.h:940
const vecng< DIM, double > & point(index_t c) const
Gets the point associated with a corner.
Definition mesh.h:1062
void set_adjacent_facet(index_t c, index_t f)
Sets the facet that a corner is adjacent to.
Definition mesh.h:1014
void set_vertex(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:987
Stores the facets of a mesh (low-level store)
Definition mesh.h:817
index_t corner(index_t f, index_t lv) const
Gets a corner by facet and local vertex index.
Definition mesh.h:860
index_t corners_end(index_t f) const
Gets the upper limit for iterating over the corners of a facet.
Definition mesh.h:838
index_t nb_corners(index_t f) const
Gets the number of corners in a facet.
Definition mesh.h:848
const index_t * corners_begin_ptr(index_t f) const
Gets a pointer to the first element for iterating over the corners of a facet.
Definition mesh.h:883
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
bool are_simplices() const
Tests whether all the facets are triangles.
Definition mesh.h:873
index_t corners_begin(index_t f) const
Gets the first element for iterating over the corners of a facet.
Definition mesh.h:827
The facets of a mesh.
Definition mesh.h:1117
index_t create_triangle(index_t v1, index_t v2, index_t v3)
Creates a triangle.
Definition mesh.h:1379
auto triangle_points(index_t f)
Decomposes a facet into triangles.
Definition mesh.h:1668
void compute_borders()
Replaces the edges of this mesh with the borders of the surfacic part.
void clear(bool keep_attributes=true, bool keep_memory=false) override
Removes all the elements and attributes.
index_t create_quad(index_t v1, index_t v2, index_t v3, index_t v4)
Creates a quad.
Definition mesh.h:1400
auto triangles(index_t f) const
Decomposes a facet into triangles.
Definition mesh.h:1618
index_t create_polygon(const vector< index_t > &vertices)
Creates a polygonal facet.
Definition mesh.h:1462
void is_not_simplicial()
Indicates that the stored elements are no longer only triangles.
Definition mesh.h:1705
void triangulate()
Triangulates the facets.
MeshFacets(Mesh &mesh)
MeshFacets constructor.
friend void tessellate_facets(Mesh &M, index_t max_nb_vertices)
Subdivides the facets with more than nb_vertices.
index_t vertex(index_t f, index_t lv) const
Gets a vertex by facet and local vertex index.
Definition mesh.h:1143
void connect(index_t facets_begin, index_t facets_end)
Connects a contiguous sequence of facets.
void reserve(index_t nb_to_reserve)
Reserves space for new facets.
Definition mesh.h:1351
void permute_elements(vector< index_t > &permutation) override
Applies a permutation to the elements and their attributes.
index_t nb_vertices(index_t f) const
Gets the number of vertices of a facet.
Definition mesh.h:1132
void is_simplicial()
Indicates that the stored elements are only triangles.
Definition mesh.h:1691
void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true) override
Deletes a set of elements.
void connect()
Connects the facets.
void flip(index_t f)
Flips a facet.
index_t create_polygon(index_t nb_vertices)
Creates a polygonal facet.
Definition mesh.h:1418
index_t create_polygon(index_t nb_vertices, const index_t *vertices)
Creates a polygonal facet.
Definition mesh.h:1440
void set_vertex(index_t f, index_t lv, index_t v)
Sets a vertex by facet and local vertex index.
Definition mesh.h:1183
auto vertices(index_t f) const
Gets the vertices of a facet.
Definition mesh.h:1553
index_t find_common_vertex(index_t f1, index_t f2) const
finds a common vertex shared by two facets
Definition mesh.h:1209
index_range corners(index_t f) const
Gets the corners of a facet.
Definition mesh.h:1538
void pop() override
Removes the last element.
index_t find_edge(index_t f, index_t v1, index_t v2) const
Finds an edge by vertex indices.
Definition mesh.h:1290
auto adjacent(index_t f) const
Gets the vertices of a facet.
Definition mesh.h:1569
index_t find_vertex(index_t f, index_t v) const
Gets the local index of a vertex in a facet.
Definition mesh.h:1194
vecng< DIM, double > & point(index_t f, index_t lv)
Gets a point by facet and local vertex index.
Definition mesh.h:1170
index_t find_adjacent(index_t f, index_t f2) const
Gets the local index of a facet adjacent to another one.
Definition mesh.h:1237
index_t prev_corner_around_facet(index_t f, index_t c) const
Gets the predecessor of a corner around a facet.
Definition mesh.h:1277
auto points(index_t f)
Gets the points associated with the vertices of a facet.
Definition mesh.h:1601
void assign_triangle_mesh(coord_index_t dim, vector< double > &vertices, vector< index_t > &triangles, bool steal_args)
Copies a triangle mesh into this Mesh.
index_t create_quads(index_t nb_quads)
Creates a contiguous chunk of quads.
Definition mesh.h:1370
index_t create_facets(index_t nb_facets, index_t nb_vertices_per_polygon)
Creates a contiguous chunk of facets.
Definition mesh.h:1321
const vecng< DIM, double > & point(index_t f, index_t lv) const
Gets a point by facet and local vertex index.
Definition mesh.h:1156
index_t adjacent(index_t f, index_t le) const
Gets an adjacent facet by facet and local edge index.
Definition mesh.h:1226
auto points(index_t f) const
Gets the points associated with the vertices of a facet.
Definition mesh.h:1584
void set_adjacent(index_t f, index_t le, index_t f2)
Sets an adjacent facet by facet and local edge index.
Definition mesh.h:1253
index_t create_triangles(index_t nb_triangles)
Creates a contiguous chunk of triangles.
Definition mesh.h:1361
index_t next_corner_around_facet(index_t f, index_t c) const
Gets the successor of a corner around a facet.
Definition mesh.h:1264
auto triangle_points(index_t f) const
Decomposes a facet into triangles.
Definition mesh.h:1644
Base class for mesh sub-element storage.
Definition mesh.h:79
index_as_iterator begin() const
Used by range-based for.
Definition mesh.h:117
virtual ~MeshSubElementsStore()
MeshElementStore destructor.
AttributesManager & attributes() const
Gets the attributes manager.
Definition mesh.h:109
MeshSubElementsStore(Mesh &mesh)
Constructs a new MeshSubElementStore.
index_t create_sub_element()
Creates attributes for a sub-element.
Definition mesh.h:189
virtual void clear_store(bool keep_attributes, bool keep_memory=false)
Removes all the elements and attributes.
index_t create_sub_elements(index_t nb)
Creates a contiguous chunk of attributes for sub-elements.
Definition mesh.h:168
index_t nb() const
Gets the number of (sub-)elements.
Definition mesh.h:98
void reserve_store(index_t nb_to_reserve)
Reserves space for new elements.
Definition mesh.h:157
index_as_iterator end() const
Used by range-based for.
Definition mesh.h:125
void copy(const MeshSubElementsStore &rhs, bool copy_attributes=true)
Copies a MeshSubElementsStore into this one.
Definition mesh.h:223
void adjust_store()
Makes the size of the store tightly match the number of the elements.
Definition mesh.h:210
virtual void resize_store(index_t new_size)
Resizes this MeshSubElementsStore.
The vertices of a mesh.
Definition mesh.h:332
void pop() override
Removes the last element.
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
void clear(bool keep_attributes=true, bool keep_memory=false) override
Removes all the elements and attributes.
auto points() const
Gets the 3D points of the mesh as an iterable sequence.
Definition mesh.h:590
index_t create_vertex(const double *coords)
Creates a new vertex.
Definition mesh.h:362
index_t create_vertex(const vecng< DIM, double > &p)
Creates a vertex from a 3d point.
Definition mesh.h:385
void assign_points(const double *points, index_t dim, index_t nb_pts)
Assigns all the points.
const float * single_precision_point_ptr(index_t v) const
Gets a (single-precision) point.
Definition mesh.h:538
const double * point_ptr(index_t v) const
Gets a point.
Definition mesh.h:477
const vecng< DIM, double > & point(index_t v) const
Gets a point.
Definition mesh.h:520
float * single_precision_point_ptr(index_t v)
Gets a (single-precision) point.
Definition mesh.h:551
auto points()
Gets the 3D points of the mesh as an iterable sequence.
Definition mesh.h:606
void remove_isolated()
Removes the vertices that have no mesh element incident to them.
void set_dimension(index_t dim)
Sets the dimension of the vertices.
Definition mesh.h:462
void set_double_precision()
Sets double precision mode.
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
void permute_elements(vector< index_t > &permutation) override
Applies a permutation to the elements and their attributes.
void assign_points(vector< double > &points, index_t dim, bool steal_arg)
Assigns all the points.
bool double_precision() const
Tests whether vertices are stored in double-precision mode.
Definition mesh.h:441
bool single_precision() const
Tests whether vertices are stored in single-precision mode.
Definition mesh.h:430
vecng< DIM, double > & point(index_t v)
Gets a point.
Definition mesh.h:504
index_t dimension() const
Gets the dimension of the vertices.
Definition mesh.h:449
index_t create_vertices(index_t nb)
Creates a contiguous chunk of vertices.
Definition mesh.h:397
void set_single_precision()
Sets single precision mode.
double * point_ptr(index_t v)
Gets a point.
Definition mesh.h:490
index_t create_vertex()
Creates a new vertex.
Definition mesh.h:353
void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true) override
Deletes a set of elements.
Represents a mesh.
Definition mesh.h:3050
Mesh(index_t dimension=3, bool single_precision=false)
Mesh constructor.
void copy(const Mesh &rhs, bool copy_attributes=true, MeshElementsFlags what=MESH_ALL_ELEMENTS)
Copies a mesh onto this one.
MeshElementsFlags
Indicates the mesh elements (vertices, facets or cells) present in a mesh.
Definition mesh.h:3029
MeshSubElementsStore & get_subelements_by_index(index_t i)
Gets a MeshSubElementsStore by index.
index_t nb_subelements_types() const
Gets the number of subelements types.
void assert_is_valid()
Does some validity checks.
static std::string subelements_type_to_name(MeshElementsFlags what)
Gets a subelement name by subelement type.
void clear(bool keep_attributes=true, bool keep_memory=false)
Removes all the elements and attributes of this mesh.
const MeshSubElementsStore & get_subelements_by_index(index_t i) const
Gets a MeshSubElementsStore by index.
virtual ~Mesh()
Mesh destructor.
std::string get_attributes() const
Gets the list of all attributes.
Mesh(const Mesh &rhs)=delete
Forbids copy.
static bool parse_attribute_name(const std::string &full_attribute_name, MeshElementsFlags &where, std::string &attribute_name, index_t &component)
Extracts localisation, name and optional component from an attribute name.
void display_attributes(const std::string &tag, const std::string &subelement_name, const MeshSubElementsStore &subelements) const
Displays the list of attributes to the Logger.
const MeshSubElementsStore & get_subelements_by_type(MeshElementsFlags what) const
Gets a MeshSubElementsStore by subelements type.
MeshSubElementsStore & get_subelements_by_type(MeshElementsFlags what)
Gets a MeshSubElementsStore by subelements type.
std::string get_vector_attributes(index_t max_dim=0) const
Gets the list of all vector attributes.
const Mesh & operator=(const Mesh &rhs)=delete
Forbids copy.
std::string get_scalar_attributes() const
Gets the list of all scalar attributes.
static MeshElementsFlags name_to_subelements_type(const std::string &name)
Gets a subelement type by subelement name.
void show_stats(const std::string &tag="Mesh") const
Displays number of vertices, facets and borders.
Wraps an integer to be used with the range-based for construct.
Definition range.h:66
A generic index_range bounded by two "non-iterators".
Definition range.h:106
Generic maths vector.
Definition vecg.h:70
T * data()
Gets modifiable vector data.
Definition vecg.h:161
Vector with aligned memory allocation.
Definition memory.h:660
T * data()
Gets a pointer to the array of elements.
Definition memory.h:806
index_t size() const
Gets the number of elements.
Definition memory.h:706
Common include file, providing basic definitions. Should be included before anything else by all head...
Geometric functions in 2d and 3d.
void copy(void *to, const void *from, size_t size)
Copies a memory block.
Definition memory.h:129
CellDescriptor * cell_type_to_cell_descriptor[GEO::MESH_NB_CELL_TYPES]
Maps a cell type to the associated cell descriptor.
uint8_t uint8
Definition numeric.h:135
Global Vorpaline namespace.
Definition basic.h:55
auto transform_range_ref(const RANGE &range, XFORM xform)
Creates a range that applies a user-defined function to each element when accessed.
Definition range.h:569
auto transform_range(const RANGE &range, XFORM xform)
Creates a range that applies a user-defined function to each element when accessed.
Definition range.h:552
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:329
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
Definition numeric.h:363
C++-20 like helpers for manipulating ranges of integers.
Lookup tables that describe the combinatorics of each cell type.
Definition mesh.h:1741
index_t nb_vertices_in_facet[6]
Definition mesh.h:1749
index_t facet_vertex[6][4]
Definition mesh.h:1754
index_t nb_vertices
Definition mesh.h:1743
index_t nb_facets
Definition mesh.h:1746
index_t edge_adjacent_facet[12][2]
Definition mesh.h:1768
index_t nb_edges
Definition mesh.h:1758
index_t edge_vertex[12][2]
Definition mesh.h:1763