Geogram Version 1.8.5
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>
47
53namespace GEO {
54
55 class Mesh;
56
57 const index_t NO_VERTEX = index_t(-1);
58 const index_t NO_EDGE = index_t(-1);
59 const index_t NO_FACET = index_t(-1);
60 const index_t NO_CELL = index_t(-1);
61 const index_t NO_CORNER = index_t(-1);
62
70 class GEOGRAM_API MeshSubElementsStore {
71 public:
72
79
84
89 index_t nb() const {
90 return nb_;
91 }
92
101 return const_cast<AttributesManager&>(attributes_);
102 }
103
109 return no_iterator(0);
110 }
111
116 no_iterator end() const {
117 return no_iterator(nb());
118 }
119
120 protected:
121
131 virtual void clear_store(
132 bool keep_attributes, bool keep_memory = false
133 );
134
141 virtual void resize_store(index_t new_size);
142
149 index_t result = nb_;
150 if(nb_ + nb > attributes_.size()) {
151 index_t new_capacity=nb_ + nb;
152 if(nb < 128) {
153 new_capacity = std::max(index_t(16),attributes_.size());
154 while(new_capacity < nb_ + nb) {
155 new_capacity *= 2;
156 }
157 }
158 attributes_.reserve(new_capacity);
159 }
160 nb_ += nb;
161 attributes_.resize(nb_);
162 return result;
163 }
164
170 index_t result = nb_;
171 ++nb_;
172 if(attributes_.capacity() < nb_) {
173 index_t new_capacity =
174 std::max(index_t(16),attributes_.capacity()*2);
175 attributes_.reserve(new_capacity);
176 }
177 attributes_.resize(nb_);
178 return result;
179 }
180
191 attributes_.resize(nb_);
192 }
193
203 void copy(
204 const MeshSubElementsStore& rhs,
205 bool copy_attributes = true
206 ) {
207 nb_ = rhs.nb();
208 if(copy_attributes) {
209 attributes_.copy(rhs.attributes_);
210 } else {
211 attributes_.clear(false,false);
212 attributes_.resize(rhs.attributes_.size());
213 }
214 }
215
216 protected:
217 Mesh& mesh_;
218 AttributesManager attributes_;
219 index_t nb_;
220 };
221
222
223 /**************************************************************************/
224
232 class GEOGRAM_API MeshElements {
233 public:
234 MeshElements();
235 virtual ~MeshElements();
236
246 virtual void delete_elements(
247 vector<index_t>& to_delete,
248 bool remove_isolated_vertices=true
249 ) = 0;
250
263 virtual void permute_elements(vector<index_t>& permutation) = 0;
264
274 virtual void clear(
275 bool keep_attributes=true, bool keep_memory=false
276 ) = 0;
277
281 virtual void pop() = 0;
282
283 protected:
291 static bool has_non_zero(const GEO::vector<index_t>& I) {
292 for(index_t i = 0; i < I.size(); i++) {
293 if(I[i] != 0) {
294 return true;
295 }
296 }
297 return false;
298 }
299 };
300
301 /**************************************************************************/
302
303 class MeshEdges;
304 class MeshFacetCornersStore;
305 class MeshCellCornersStore;
306
311 class GEOGRAM_API MeshVertices :
312 public MeshSubElementsStore, public MeshElements {
313 public:
314 MeshVertices(Mesh& mesh);
315 ~MeshVertices() override;
316
322
324 vector<index_t>& to_delete, bool remove_isolated_vertices=true
325 ) override;
326
327 void permute_elements(vector<index_t>& permutation) override;
328
334 return MeshSubElementsStore::create_sub_element();
335 }
336
342 index_t create_vertex(const double* coords) {
343 // Sanity check:
344 // It is not correct to call create_vertex(point_ptr(v)) since
345 // create_vertex may realloc the points coordinates vector, thus
346 // invalidate point_ptr(v).
348 nb() == 0 ||
349 coords < point_ptr(0) ||
350 coords >= point_ptr(0) + nb() * dimension()
351 );
352 index_t result = create_vertex();
353 for(index_t c=0; c<dimension(); ++c) {
354 point_ptr(result)[c] = coords[c];
355 }
356 return result;
357 }
358
365 return MeshSubElementsStore::create_sub_elements(nb);
366 }
367
368 void clear(
369 bool keep_attributes=true, bool keep_memory=false
370 ) override;
371
380
390
397 bool single_precision() const {
398 return point_fp32_.is_bound();
399 }
400
408 bool double_precision() const {
409 return point_.is_bound();
410 }
411
417 return
418 single_precision() ?
419 point_fp32_.dimension() :
420 point_.dimension() ;
421 }
422
430 if(single_precision()) {
431 point_fp32_.redim(dim);
432 } else {
433 point_.redim(dim);
434 }
435 }
436
444 const double* point_ptr(index_t v) const {
445 geo_debug_assert(v < nb());
446 geo_debug_assert(!single_precision());
447 return &point_[v*point_.dimension()];
448 }
449
457 double* point_ptr(index_t v) {
458 geo_debug_assert(v < nb());
459 geo_debug_assert(!single_precision());
460 return &point_[v*point_.dimension()];
461 }
462
463
472 geo_debug_assert(v < nb());
473 geo_debug_assert(!single_precision());
474 geo_debug_assert(dimension() >= 3);
475 return *(vec3*)(&point_[v*point_.dimension()]);
476 }
477
485 const vec3& point(index_t v) const {
486 geo_debug_assert(v < nb());
487 geo_debug_assert(!single_precision());
488 geo_debug_assert(dimension() >= 3);
489 return *(const vec3*)(&point_[v*point_.dimension()]);
490 }
491
499 const float* single_precision_point_ptr(index_t v) const {
500 geo_debug_assert(v < nb());
501 geo_debug_assert(single_precision());
502 return &point_fp32_[v*point_fp32_.dimension()];
503 }
504
513 geo_debug_assert(v < nb());
514 geo_debug_assert(single_precision());
515 return &point_fp32_[v*point_fp32_.dimension()];
516 }
517
528 vector<double>& points, index_t dim, bool steal_arg
529 );
530
540 const double* points, index_t dim, index_t nb_pts
541 );
542
543 void pop() override;
544
545 protected:
546
548 bool keep_attributes, bool keep_memory = false
549 ) override;
550
551 void resize_store(index_t new_size) override;
552
553 void bind_point_attribute(index_t dim, bool single_precision=false);
554
555 void copy(const MeshVertices& rhs, bool copy_attributes=true) {
556 index_t dim = rhs.dimension();
557 if(point_fp32_.is_bound()) {
558 point_fp32_.destroy();
559 }
560 if(point_.is_bound()) {
561 point_.destroy();
562 }
563 MeshSubElementsStore::copy(rhs, copy_attributes);
564 if(rhs.single_precision()) {
565 point_fp32_.bind_if_is_defined(attributes(),"point_fp32");
566 if(!point_fp32_.is_bound()) {
567 point_fp32_.create_vector_attribute(
568 attributes(), "point_fp32", dim
569 );
570 }
571 } else {
572 point_.bind_if_is_defined(attributes(),"point");
573 if(!point_.is_bound()) {
574 point_.create_vector_attribute(
575 attributes(), "point", dim
576 );
577 }
578 }
579 // Even if we do not copy the attributes, we need at least
580 // to copy the coordinates of the points !!
581 if(!copy_attributes) {
582 if(rhs.single_precision()) {
583 Memory::copy(
584 single_precision_point_ptr(0),
586 rhs.dimension()*rhs.nb()*sizeof(float)
587 );
588 } else {
589 Memory::copy(
590 point_ptr(0),
591 rhs.point_ptr(0),
592 rhs.dimension()*rhs.nb()*sizeof(double)
593 );
594 }
595 }
596 }
597
598 MeshEdges& edges_;
599 MeshFacetCornersStore& facet_corners_;
600 MeshCellCornersStore& cell_corners_;
601 Attribute<double> point_;
602 Attribute<float> point_fp32_;
603
604 friend class Mesh;
605 friend class GeogramIOHandler;
606 };
607
608 /*************************************************************************/
609
614 class GEOGRAM_API MeshEdges :
615 public MeshSubElementsStore, public MeshElements {
616 public:
617 MeshEdges(Mesh& mesh);
618 ~MeshEdges() override;
619
627 geo_debug_assert(e < nb());
628 geo_debug_assert(lv < 2);
629 return edge_vertex_[2*e+lv];
630 }
631
639 geo_debug_assert(e < nb());
640 geo_debug_assert(lv < 2);
641 edge_vertex_[2*e+lv] = v;
642 }
643
644
652 geo_debug_assert(c < 2*nb());
653 return &(edge_vertex_[c]);
654 }
655
663 geo_debug_assert(c < 2*nb());
664 return &(edge_vertex_[c]);
665 }
666
672 return create_sub_element();
673 }
674
681 return create_sub_elements(nb);
682 }
683
690 index_t result = create_edge();
691 set_vertex(result,0,v1);
692 set_vertex(result,1,v2);
693 return result;
694 }
695
697 vector<index_t>& to_delete, bool remove_isolated_vertices=true
698 ) override;
699
700 void permute_elements(vector<index_t>& permutation) override;
701
702 void clear(
703 bool keep_attributes=true, bool keep_memory=false
704 ) override;
705
706 void pop() override;
707
708 protected:
710 bool keep_attributes, bool keep_memory = false
711 ) override;
712
713 void resize_store(index_t new_size) override;
714
715 index_t create_sub_element() {
716 edge_vertex_.push_back(NO_VERTEX);
717 edge_vertex_.push_back(NO_VERTEX);
718 return MeshSubElementsStore::create_sub_element();
719 }
720
721 index_t create_sub_elements(index_t nb_in) {
722 edge_vertex_.resize(2*(nb()+nb_in),NO_VERTEX);
723 return MeshSubElementsStore::create_sub_elements(nb_in);
724 }
725
726 void copy(const MeshEdges& rhs, bool copy_attributes=true) {
727 MeshSubElementsStore::copy(rhs, copy_attributes);
728 edge_vertex_ = rhs.edge_vertex_;
729 }
730
731 vector<index_t> edge_vertex_;
732 friend class Mesh;
733 friend class GeogramIOHandler;
734 };
735
736 /**************************************************************************/
737
742 class GEOGRAM_API MeshFacetsStore : public MeshSubElementsStore {
743 public:
744 MeshFacetsStore(Mesh& mesh);
745
753 geo_debug_assert(f < nb());
754 return (is_simplicial_ ? 3*f : facet_ptr_[f]);
755 }
756
764 geo_debug_assert(f < nb());
765 return (is_simplicial_ ? 3*(f+1): facet_ptr_[f+1]);
766 }
767
774 geo_debug_assert(f < nb());
775 return (is_simplicial_ ? 3 : facet_ptr_[f+1] - facet_ptr_[f]);
776 }
777
786 geo_debug_assert(f < nb());
787 geo_debug_assert(lv < nb_corners(f));
788 return corners_begin(f)+lv;
789 }
790
798 bool are_simplices() const {
799 return is_simplicial_;
800 }
801
809 geo_debug_assert(!is_simplicial_);
810 geo_debug_assert(f < nb());
811 return &facet_ptr_[f];
812 }
813
814 protected:
816 bool keep_attributes, bool keep_memory = false
817 ) override;
818
819 void resize_store(index_t new_size) override;
820
821 index_t create_sub_element() {
822 if(!is_simplicial_) {
823 facet_ptr_.push_back(NO_CORNER);
824 }
825 return MeshSubElementsStore::create_sub_element();
826 }
827
828 index_t create_sub_elements(index_t nb) {
829 if(!is_simplicial_) {
830 for(index_t i=0; i<nb; ++i) {
831 facet_ptr_.push_back(NO_CORNER);
832 }
833 }
834 return MeshSubElementsStore::create_sub_elements(nb);
835 }
836
837 void copy(const MeshFacetsStore& rhs, bool copy_attributes=true) {
838 MeshSubElementsStore::copy(rhs,copy_attributes);
839 is_simplicial_ = rhs.is_simplicial_;
840 facet_ptr_ = rhs.facet_ptr_;
841 }
842
843 protected:
844 bool is_simplicial_;
845 vector<index_t> facet_ptr_;
846 friend class Mesh;
847 friend class GeogramIOHandler;
848 };
849
850 /*************************************************************************/
851
856 class GEOGRAM_API MeshFacetCornersStore : public MeshSubElementsStore {
857 public:
859
866 geo_assert(c < nb());
867 return corner_vertex_[c];
868 }
869
877 geo_assert(c < nb());
878 return corner_adjacent_facet_[c];
879 }
880
889 geo_assert(c < nb());
890 return &corner_adjacent_facet_[c];
891 }
892
893
902 geo_assert(c < nb());
903 return &corner_adjacent_facet_[c];
904 }
905
913 geo_debug_assert(c < nb());
914 geo_debug_assert(v < vertices_.nb());
915 corner_vertex_[c] = v;
916 }
917
929 geo_debug_assert(c < nb());
930 corner_vertex_[c] = v;
931 }
932
940 geo_debug_assert(c < nb());
941 geo_debug_assert(f == NO_FACET || f < facets_.nb());
942 corner_adjacent_facet_[c] = f;
943 }
944
953 geo_debug_assert(c < nb());
954 return &(corner_vertex_[c]);
955 }
956
965 geo_debug_assert(c < nb());
966 return &(corner_vertex_[c]);
967 }
968
969 protected:
971 bool keep_attributes, bool keep_memory = false
972 ) override;
973
974 void resize_store(index_t new_size) override;
975
976 index_t create_sub_element(index_t v, index_t f = NO_FACET) {
977 corner_vertex_.push_back(v);
978 corner_adjacent_facet_.push_back(f);
979 return MeshSubElementsStore::create_sub_element();
980 }
981
982 index_t create_sub_elements(index_t nb) {
983 for(index_t i=0; i<nb; ++i) {
984 corner_vertex_.push_back(NO_VERTEX);
985 }
986 for(index_t i=0; i<nb; ++i) {
987 corner_adjacent_facet_.push_back(NO_FACET);
988 }
989 return MeshSubElementsStore::create_sub_elements(nb);
990 }
991
992 void copy(
993 const MeshFacetCornersStore& rhs, bool copy_attributes=true
994 ) {
995 MeshSubElementsStore::copy(rhs, copy_attributes);
996 corner_vertex_ = rhs.corner_vertex_;
997 corner_adjacent_facet_ = rhs.corner_adjacent_facet_;
998 }
999
1000 protected:
1001 MeshVertices& vertices_;
1002 MeshFacetsStore& facets_;
1003 vector<index_t> corner_vertex_;
1004 vector<index_t> corner_adjacent_facet_;
1005
1006 friend class MeshFacets;
1007 friend class Mesh;
1008 friend class GeogramIOHandler;
1009 };
1010
1011 /*************************************************************************/
1012
1017 class GEOGRAM_API MeshFacets : public MeshFacetsStore, public MeshElements {
1018 public:
1019
1026
1033 return nb_corners(f);
1034 }
1035
1044 return facet_corners_.vertex(corner(f,lv));
1045 }
1046
1055 facet_corners_.set_vertex(corner(f,lv),v);
1056 }
1057
1066 for(index_t lv=0; lv<nb_vertices(f); ++lv) {
1067 if(vertex(f,lv) == v) {
1068 return lv;
1069 }
1070 }
1071 return NO_VERTEX;
1072 }
1073
1081 for(index_t lv=0; lv<nb_vertices(f1); ++lv) {
1082 index_t v = vertex(f1,lv);
1083 if(find_vertex(f2,v) != NO_VERTEX) {
1084 return lv;
1085 }
1086 }
1087 return NO_VERTEX;
1088 }
1089
1098 return facet_corners_.adjacent_facet(corner(f,le));
1099 }
1100
1109 for(index_t le=0; le<nb_vertices(f); ++le) {
1110 if(adjacent(f,le) == f2) {
1111 return le;
1112 }
1113 }
1114 return NO_FACET;
1115 }
1116
1125 facet_corners_.set_adjacent_facet(corner(f,le),f2);
1126 }
1127
1136 geo_debug_assert(f < nb());
1137 geo_debug_assert(c >= corners_begin(f) && c < corners_end(f));
1138 return c + 1 == corners_end(f) ? corners_begin(f) : c + 1;
1139 }
1140
1149 geo_debug_assert(f < nb());
1150 geo_debug_assert(c >= corners_begin(f) && c < corners_end(f));
1151 return c == corners_begin(f) ? corners_end(f) - 1 : c - 1;
1152 }
1153
1155 vector<index_t>& to_delete,
1156 bool remove_isolated_vertices=true
1157 ) override;
1158
1159 void permute_elements(vector<index_t>& permutation) override;
1160
1161 void clear(
1162 bool keep_attributes=true, bool keep_memory=false
1163 ) override;
1164
1173 index_t nb_facets, index_t nb_vertices_per_polygon
1174 ) {
1175 if(nb_vertices_per_polygon != 3) {
1176 is_not_simplicial();
1177 }
1178
1179 index_t first_facet = nb();
1180 index_t co = facet_corners_.nb();
1181 facet_corners_.create_sub_elements(
1182 nb_facets*nb_vertices_per_polygon
1183 );
1184 index_t result = create_sub_elements(nb_facets);
1185
1186 if(!is_simplicial_) {
1187 for(index_t f=first_facet; f<=first_facet+nb_facets; ++f) {
1188 facet_ptr_[f] = co;
1189 co += nb_vertices_per_polygon;
1190 }
1191 geo_debug_assert(facet_ptr_.size() == nb()+1);
1192 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1193 }
1194 return result;
1195 }
1196
1203 return create_facets(nb_triangles, 3);
1204 }
1205
1212 return create_facets(nb_quads, 4);
1213 }
1214
1221 facet_corners_.create_sub_element(v1);
1222 facet_corners_.create_sub_element(v2);
1223 facet_corners_.create_sub_element(v3);
1224 index_t result = create_sub_element();
1225 if(!is_simplicial_) {
1226 facet_ptr_[result+1] = facet_corners_.nb();
1227 geo_debug_assert(facet_ptr_.size() == nb()+1);
1228 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1229 }
1230 return result;
1231 }
1232
1239 is_not_simplicial();
1240 facet_corners_.create_sub_element(v1);
1241 facet_corners_.create_sub_element(v2);
1242 facet_corners_.create_sub_element(v3);
1243 facet_corners_.create_sub_element(v4);
1244 index_t result = create_sub_element();
1245 facet_ptr_[result+1] = facet_corners_.nb();
1246 geo_debug_assert(facet_ptr_.size() == nb()+1);
1247 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1248 return result;
1249 }
1250
1257 if(nb_vertices != 3) {
1258 is_not_simplicial();
1259 }
1260 for(index_t i=0; i<nb_vertices; ++i) {
1261 facet_corners_.create_sub_element(NO_VERTEX);
1262 }
1263 index_t result = create_sub_element();
1264 if(!is_simplicial_) {
1265 facet_ptr_[result+1] = facet_corners_.nb();
1266 geo_debug_assert(facet_ptr_.size() == nb()+1);
1267 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1268 }
1269 return result;
1270 }
1271
1278 index_t create_polygon(index_t nb_vertices, const index_t* vertices) {
1279 if(nb_vertices != 3) {
1280 is_not_simplicial();
1281 }
1282 for(index_t i=0; i<nb_vertices; ++i) {
1283 facet_corners_.create_sub_element(vertices[i]);
1284 }
1285 index_t result = create_sub_element();
1286 if(!is_simplicial_) {
1287 facet_ptr_[result+1] = facet_corners_.nb();
1288 geo_debug_assert(facet_ptr_.size() == nb()+1);
1289 geo_debug_assert(facet_ptr_[nb()] == facet_corners_.nb());
1290 }
1291 return result;
1292 }
1293
1301 return create_polygon(vertices.size(), vertices.data());
1302 }
1303
1307 void connect();
1308
1314
1320 void flip(index_t f);
1321
1327
1340 coord_index_t dim,
1341 vector<double>& vertices,
1342 vector<index_t>& triangles,
1343 bool steal_args
1344 );
1345
1346 /*
1347 * \brief Copies a triangle mesh into this Mesh.
1348 * \details Facet adjacence are not computed.
1349 * Facet and corner attributes are zeroed.
1350 * \param[in] triangles facet to vertex links
1351 * \param[in] steal_args if set, vertices and triangles
1352 * are 'stolen' from the arguments
1353 * (using vector::swap).
1354 */
1355 void assign_triangle_mesh(
1356 vector<index_t>& triangles,
1357 bool steal_args
1358 );
1359
1360 void pop() override;
1361
1368 geo_debug_assert(f < nb());
1369 return range<no_iterator>(
1370 no_iterator(corners_begin(f)),
1371 no_iterator(corners_end(f))
1372 );
1373 }
1374
1375 protected:
1376
1381 if(!is_simplicial_) {
1382 is_simplicial_ = true;
1383 facet_ptr_.resize(1);
1384 facet_ptr_[0] = 0;
1385 }
1386 }
1387
1395 if(is_simplicial_) {
1396 is_simplicial_ = false;
1397 facet_ptr_.resize(nb()+1);
1398 for(index_t f=0; f<facet_ptr_.size(); ++f) {
1399 facet_ptr_[f] = 3*f;
1400 }
1401 }
1402 }
1403
1404 protected:
1405 MeshVertices& vertices_;
1406 MeshFacetCornersStore& facet_corners_;
1407 friend class Mesh;
1408 friend class GeogramIOHandler;
1409 friend void GEOGRAM_API tessellate_facets(
1410 Mesh& M, index_t max_nb_vertices
1411 );
1412 };
1413
1414 /*************************************************************************/
1415
1416 enum MeshCellType {
1417 MESH_TET = 0,
1418 MESH_HEX = 1,
1419 MESH_PRISM = 2,
1420 MESH_PYRAMID = 3,
1421 MESH_CONNECTOR = 4,
1422 MESH_NB_CELL_TYPES = 5
1423 };
1424
1459
1460
1467 namespace MeshCellDescriptors {
1471 GEOGRAM_API extern CellDescriptor*
1472 cell_type_to_cell_descriptor[GEO::MESH_NB_CELL_TYPES];
1473
1474 GEOGRAM_API extern CellDescriptor tet_descriptor;
1475 GEOGRAM_API extern CellDescriptor hex_descriptor;
1476 GEOGRAM_API extern CellDescriptor prism_descriptor;
1477 GEOGRAM_API extern CellDescriptor pyramid_descriptor;
1478 GEOGRAM_API extern CellDescriptor connector_descriptor;
1479 }
1480
1485 class GEOGRAM_API MeshCellsStore : public MeshSubElementsStore {
1486 public:
1487 MeshCellsStore(Mesh& mesh);
1488
1496 bool are_simplices() const {
1497 return is_simplicial_;
1498 }
1499
1506 MeshCellType type(index_t c) const {
1507 geo_debug_assert(c < nb());
1508 return is_simplicial_ ? MESH_TET : MeshCellType(cell_type_[c]);
1509 }
1510
1520 geo_debug_assert(c < nb());
1521 return is_simplicial_ ? MeshCellDescriptors::tet_descriptor :
1522 *(
1523 MeshCellDescriptors::cell_type_to_cell_descriptor[
1524 cell_type_[c]
1525 ]
1526 );
1527 }
1528
1539 MeshCellType t
1540 ) {
1541 geo_debug_assert(t < GEO::MESH_NB_CELL_TYPES);
1542 return *(MeshCellDescriptors::cell_type_to_cell_descriptor[t]);
1543 }
1544
1551 geo_debug_assert(c < nb());
1552 return descriptor(c).nb_vertices;
1553 }
1554
1562 geo_debug_assert(c < nb());
1563 return is_simplicial_ ? 4*c : cell_ptr_[c];
1564 }
1565
1573 geo_debug_assert(c < nb());
1574 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_corners(c);
1575 }
1576
1584 geo_debug_assert(c < nb());
1585 // There seems to be a linkage problem under MSVC for the
1586 // following assertion check...
1587#ifndef GEO_OS_WINDOWS
1588 geo_debug_assert(lv < nb_corners(c));
1589#endif
1590 return corners_begin(c) + lv;
1591 }
1592
1599 geo_debug_assert(c < nb());
1600 return descriptor(c).nb_facets;
1601 }
1602
1610 geo_debug_assert(c < nb());
1611 return is_simplicial_ ? 4*c : cell_ptr_[c];
1612 }
1613
1621 geo_debug_assert(c < nb());
1622 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_facets(c);
1623 }
1624
1632 geo_debug_assert(c < nb());
1633 geo_debug_assert(lf < nb_facets(c));
1634 return facets_begin(c) + lf;
1635 }
1636
1643 return descriptor(c).nb_edges;
1644 }
1645
1646 protected:
1648 bool keep_attributes, bool keep_memory = false
1649 ) override;
1650
1651 void resize_store(index_t new_size) override;
1652
1653 index_t create_sub_element(MeshCellType type) {
1654 if(!is_simplicial_) {
1655 cell_ptr_.push_back(NO_CORNER);
1656 cell_type_.push_back(Numeric::uint8(type));
1657 }
1658 return MeshSubElementsStore::create_sub_element();
1659 }
1660
1661 index_t create_sub_elements(index_t nb, MeshCellType type) {
1662 if(!is_simplicial_) {
1663 for(index_t i=0; i<nb; ++i) {
1664 cell_ptr_.push_back(NO_CORNER);
1665 cell_type_.push_back(Numeric::uint8(type));
1666 }
1667 }
1668 return MeshSubElementsStore::create_sub_elements(nb);
1669 }
1670
1671 void copy(
1672 const MeshCellsStore& rhs, bool copy_attributes=true
1673 ) {
1674 MeshSubElementsStore::copy(rhs, copy_attributes);
1675 is_simplicial_ = rhs.is_simplicial_;
1676 cell_type_ = rhs.cell_type_;
1677 cell_ptr_ = rhs.cell_ptr_;
1678 }
1679
1680 protected:
1681 bool is_simplicial_;
1682 vector<Numeric::uint8> cell_type_;
1683 vector<index_t> cell_ptr_;
1684
1685 protected:
1686 friend class Mesh;
1687 friend class GeogramIOHandler;
1688 };
1689
1690 /*************************************************************************/
1691
1696 class GEOGRAM_API MeshCellCornersStore : public MeshSubElementsStore {
1697 public:
1699
1706 geo_assert(c < nb());
1707 return corner_vertex_[c];
1708 }
1709
1716 geo_debug_assert(c < nb());
1717 geo_debug_assert(v < vertices_.nb());
1718 corner_vertex_[c] = v;
1719 }
1720
1729 geo_debug_assert(c < nb());
1730 return &(corner_vertex_[c]);
1731 }
1732
1741 geo_debug_assert(c < nb());
1742 return &(corner_vertex_[c]);
1743 }
1744
1745 protected:
1747 bool keep_attributes, bool keep_memory = false
1748 ) override;
1749
1750 void resize_store(index_t new_size) override;
1751
1752 index_t create_sub_element(index_t v) {
1753 corner_vertex_.push_back(v);
1754 return MeshSubElementsStore::create_sub_element();
1755 }
1756
1757 index_t create_sub_elements(index_t nb) {
1758 for(index_t i=0; i<nb; ++i) {
1759 corner_vertex_.push_back(NO_VERTEX);
1760 }
1761 return MeshSubElementsStore::create_sub_elements(nb);
1762 }
1763
1764 void copy(
1765 const MeshCellCornersStore& rhs, bool copy_attributes=true
1766 ) {
1767 MeshSubElementsStore::copy(rhs, copy_attributes);
1768 corner_vertex_ = rhs.corner_vertex_;
1769 }
1770
1771 protected:
1772 MeshVertices& vertices_;
1773 vector<index_t> corner_vertex_;
1774
1775 friend class MeshCells;
1776 friend class Mesh;
1777 friend class GeogramIOHandler;
1778 };
1779
1780 /*************************************************************************/
1781
1786 class GEOGRAM_API MeshCellFacetsStore : public MeshSubElementsStore {
1787 public:
1793
1801 geo_assert(f < nb());
1802 return adjacent_cell_[f];
1803 }
1804
1813 geo_debug_assert(f < nb());
1814 geo_debug_assert(c == NO_CELL || c < cells_.nb());
1815 adjacent_cell_[f] = c;
1816 }
1817
1825 geo_assert(f < nb());
1826 return &adjacent_cell_[f];
1827 }
1828
1836 geo_assert(f < nb());
1837 return &adjacent_cell_[f];
1838 }
1839
1840 protected:
1842 bool keep_attributes, bool keep_memory = false
1843 ) override;
1844
1845 void resize_store(index_t new_size) override;
1846
1847 index_t create_sub_element(index_t c = NO_CELL) {
1848 adjacent_cell_.push_back(c);
1849 return MeshSubElementsStore::create_sub_element();
1850 }
1851
1852 index_t create_sub_elements(index_t nb) {
1853 for(index_t i=0; i<nb; ++i) {
1854 adjacent_cell_.push_back(NO_CELL);
1855 }
1856 return MeshSubElementsStore::create_sub_elements(nb);
1857 }
1858
1859 void copy(
1860 const MeshCellFacetsStore& rhs, bool copy_attributes=true
1861 ) {
1862 MeshSubElementsStore::copy(rhs, copy_attributes);
1863 adjacent_cell_ = rhs.adjacent_cell_;
1864 }
1865
1866 protected:
1867 MeshVertices& vertices_;
1868 MeshCellsStore& cells_;
1869 vector<index_t> adjacent_cell_;
1870
1871 friend class MeshCells;
1872 friend class Mesh;
1873 friend class GeogramIOHandler;
1874 };
1875
1876 /*************************************************************************/
1877
1882 class GEOGRAM_API MeshCells : public MeshCellsStore, public MeshElements {
1883 public:
1889
1896 return nb_corners(c);
1897 }
1898
1906 return cell_corners_.vertex(corner(c,lv));
1907 }
1908
1916 cell_corners_.set_vertex(corner(c,lv),v);
1917 }
1918
1927 return cell_facets_.adjacent_cell(facet(c,lf));
1928 }
1929
1938 cell_facets_.set_adjacent_cell(facet(c,lf),c2);
1939 }
1940
1948 geo_debug_assert(lf < nb_facets(c));
1949 return descriptor(c).nb_vertices_in_facet[lf];
1950 }
1951
1961 geo_debug_assert(lv < facet_nb_vertices(c, lf));
1962 return cell_corners_.vertex(
1963 corner(c, descriptor(c).facet_vertex[lf][lv])
1964 );
1965 }
1975 geo_debug_assert(lc < facet_nb_vertices(c, lf));
1976 return corner(c, descriptor(c).facet_vertex[lf][lc]);
1977 }
1978
1988 geo_debug_assert(le < nb_edges(c));
1989 geo_debug_assert(lv < 2);
1990 return cell_corners_.vertex(
1991 corner(c,descriptor(c).edge_vertex[le][lv])
1992 );
1993 }
1994
2006 geo_debug_assert(le < nb_edges(c));
2007 geo_debug_assert(lf < 2);
2008 return descriptor(c).edge_adjacent_facet[le][lf];
2009 }
2010
2017 geo_debug_assert(c < nb());
2018 return range<no_iterator>(
2019 no_iterator(corners_begin(c)),
2020 no_iterator(corners_end(c))
2021 );
2022 }
2023
2024 void clear(
2025 bool keep_attributes=true, bool keep_memory=false
2026 ) override;
2027
2029 vector<index_t>& to_delete,
2030 bool remove_isolated_vertices=true
2031 ) override;
2032
2033 void permute_elements(vector<index_t>& permutation) override;
2034
2043 index_t create_cells(index_t nb_cells, MeshCellType type) {
2044
2045 if(nb_cells == 0) {
2046 return NO_CELL;
2047 }
2048
2049
2050 if(type != MESH_TET) {
2051 is_not_simplicial();
2052 }
2053
2054 const CellDescriptor& desc = cell_type_to_cell_descriptor(type);
2055
2056 // Note: there is padding, the same number of corners and
2057 // faces is created for each cell, so that a single cell
2058 // pointer is used for both.
2059
2060 index_t cell_size = std::max(desc.nb_vertices, desc.nb_facets);
2061 index_t first_cell = nb();
2062 index_t co = cell_corners_.nb();
2063
2064 cell_corners_.create_sub_elements(
2065 nb_cells*cell_size
2066 );
2067
2068 cell_facets_.create_sub_elements(
2069 nb_cells*cell_size
2070 );
2071
2072 index_t result = create_sub_elements(nb_cells, type);
2073
2074 if(!is_simplicial_) {
2075 for(index_t c=first_cell; c<=first_cell+nb_cells; ++c) {
2076 cell_ptr_[c] = co;
2077 co += cell_size;
2078 }
2079
2080 geo_debug_assert(cell_ptr_.size() == nb()+1);
2081 geo_debug_assert(cell_ptr_[nb()] == cell_corners_.nb());
2082 geo_debug_assert(cell_ptr_[nb()] == cell_facets_.nb());
2083 }
2084
2085 return result;
2086 }
2087
2094 return create_cells(nb_tets, MESH_TET);
2095 }
2096
2103 return create_cells(nb_hexes, MESH_HEX);
2104 }
2105
2112 return create_cells(nb_prisms, MESH_PRISM);
2113 }
2114
2121 return create_cells(nb_pyramids, MESH_PYRAMID);
2122 }
2123
2133 index_t v1, index_t v2, index_t v3, index_t v4,
2134 index_t adj1 = NO_CELL,
2135 index_t adj2 = NO_CELL,
2136 index_t adj3 = NO_CELL,
2137 index_t adj4 = NO_CELL
2138 ) {
2139 cell_corners_.create_sub_element(v1);
2140 cell_corners_.create_sub_element(v2);
2141 cell_corners_.create_sub_element(v3);
2142 cell_corners_.create_sub_element(v4);
2143 cell_facets_.create_sub_element(adj1);
2144 cell_facets_.create_sub_element(adj2);
2145 cell_facets_.create_sub_element(adj3);
2146 cell_facets_.create_sub_element(adj4);
2147 index_t result = create_sub_element(MESH_TET);
2148 if(!is_simplicial_) {
2149 cell_ptr_[nb()] = cell_corners_.nb();
2150 }
2151 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2152 return result;
2153 }
2154
2165 index_t v1, index_t v2, index_t v3, index_t v4,
2166 index_t v5, index_t v6, index_t v7, index_t v8,
2167 index_t adj1 = NO_CELL,
2168 index_t adj2 = NO_CELL,
2169 index_t adj3 = NO_CELL,
2170 index_t adj4 = NO_CELL,
2171 index_t adj5 = NO_CELL,
2172 index_t adj6 = NO_CELL
2173 ) {
2174 is_not_simplicial();
2175 cell_corners_.create_sub_element(v1);
2176 cell_corners_.create_sub_element(v2);
2177 cell_corners_.create_sub_element(v3);
2178 cell_corners_.create_sub_element(v4);
2179 cell_corners_.create_sub_element(v5);
2180 cell_corners_.create_sub_element(v6);
2181 cell_corners_.create_sub_element(v7);
2182 cell_corners_.create_sub_element(v8);
2183 cell_facets_.create_sub_element(adj1);
2184 cell_facets_.create_sub_element(adj2);
2185 cell_facets_.create_sub_element(adj3);
2186 cell_facets_.create_sub_element(adj4);
2187 cell_facets_.create_sub_element(adj5);
2188 cell_facets_.create_sub_element(adj6);
2189 cell_facets_.create_sub_element(NO_CELL); // padding
2190 cell_facets_.create_sub_element(NO_CELL); // padding
2191 index_t result = create_sub_element(MESH_HEX);
2192 cell_ptr_[nb()] = cell_corners_.nb();
2193 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2194 return result;
2195 }
2196
2207 index_t v1, index_t v2,
2208 index_t v3, index_t v4,
2209 index_t v5, index_t v6,
2210 index_t adj1 = NO_CELL,
2211 index_t adj2 = NO_CELL,
2212 index_t adj3 = NO_CELL,
2213 index_t adj4 = NO_CELL,
2214 index_t adj5 = NO_CELL
2215 ) {
2216 is_not_simplicial();
2217 cell_corners_.create_sub_element(v1);
2218 cell_corners_.create_sub_element(v2);
2219 cell_corners_.create_sub_element(v3);
2220 cell_corners_.create_sub_element(v4);
2221 cell_corners_.create_sub_element(v5);
2222 cell_corners_.create_sub_element(v6);
2223 cell_facets_.create_sub_element(adj1);
2224 cell_facets_.create_sub_element(adj2);
2225 cell_facets_.create_sub_element(adj3);
2226 cell_facets_.create_sub_element(adj4);
2227 cell_facets_.create_sub_element(adj5);
2228 cell_facets_.create_sub_element(NO_CELL); // padding
2229 index_t result = create_sub_element(MESH_PRISM);
2230 cell_ptr_[nb()] = cell_corners_.nb();
2231 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2232 return result;
2233 }
2234
2245 index_t v1, index_t v2, index_t v3, index_t v4, index_t v5,
2246 index_t adj1 = NO_CELL,
2247 index_t adj2 = NO_CELL,
2248 index_t adj3 = NO_CELL,
2249 index_t adj4 = NO_CELL,
2250 index_t adj5 = NO_CELL
2251 ) {
2252 is_not_simplicial();
2253 cell_corners_.create_sub_element(v1);
2254 cell_corners_.create_sub_element(v2);
2255 cell_corners_.create_sub_element(v3);
2256 cell_corners_.create_sub_element(v4);
2257 cell_corners_.create_sub_element(v5);
2258 cell_facets_.create_sub_element(adj1);
2259 cell_facets_.create_sub_element(adj2);
2260 cell_facets_.create_sub_element(adj3);
2261 cell_facets_.create_sub_element(adj4);
2262 cell_facets_.create_sub_element(adj5);
2263 index_t result = create_sub_element(MESH_PYRAMID);
2264 cell_ptr_[nb()] = cell_corners_.nb();
2265 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2266 return result;
2267 }
2268
2282 index_t v1, index_t v2, index_t v3, index_t v4,
2283 index_t adj1 = NO_CELL,
2284 index_t adj2 = NO_CELL,
2285 index_t adj3 = NO_CELL
2286 ) {
2287 is_not_simplicial();
2288 cell_corners_.create_sub_element(v1);
2289 cell_corners_.create_sub_element(v2);
2290 cell_corners_.create_sub_element(v3);
2291 cell_corners_.create_sub_element(v4);
2292 cell_facets_.create_sub_element(adj1);
2293 cell_facets_.create_sub_element(adj2);
2294 cell_facets_.create_sub_element(adj3);
2295 cell_facets_.create_sub_element(NO_CELL); // padding
2296 index_t result = create_sub_element(MESH_CONNECTOR);
2297 cell_ptr_[nb()] = cell_corners_.nb();
2298 geo_debug_assert(cell_facets_.nb() == cell_corners_.nb());
2299 return result;
2300 }
2301
2313 bool remove_trivial_slivers = true, bool verbose_if_OK=false
2314 );
2315
2321
2330
2342 coord_index_t dim,
2343 vector<double>& vertices,
2344 vector<index_t>& tets,
2345 bool steal_args
2346 );
2347
2357 vector<index_t>& tets,
2358 bool steal_args
2359 );
2360
2361 void pop() override;
2362
2363 index_t tet_adjacent(index_t t, index_t lf) const {
2364 geo_debug_assert(is_simplicial_);
2365 geo_debug_assert(t < nb());
2366 geo_debug_assert(lf < 4);
2367 return cell_facets_.adjacent_cell_[4*t+lf];
2368 }
2369
2370 index_t find_tet_adjacent(index_t t, index_t t2) const {
2371 geo_debug_assert(is_simplicial_);
2372 geo_debug_assert(t < nb());
2373 geo_debug_assert(t2 < nb());
2374 for(index_t lf=0; lf<4; ++lf) {
2375 if(cell_facets_.adjacent_cell_[4*t+lf] == t2) {
2376 return lf;
2377 }
2378 }
2379 return NO_FACET;
2380 }
2381
2382 index_t tet_vertex(index_t t, index_t lv) const {
2383 geo_debug_assert(is_simplicial_);
2384 geo_debug_assert(t < nb());
2385 geo_debug_assert(lv < 4);
2386 return cell_corners_.corner_vertex_[4*t+lv];
2387 }
2388
2389 index_t find_tet_vertex(index_t t, index_t v) const {
2390 geo_debug_assert(is_simplicial_);
2391 geo_debug_assert(t < nb());
2392 geo_debug_assert(v < vertices_.nb());
2393 for(index_t lv=0; lv<4; ++lv) {
2394 if(cell_corners_.corner_vertex_[4*t+lv] == v) {
2395 return lv;
2396 }
2397 }
2398 return NO_VERTEX;
2399 }
2400
2412 index_t t, index_t lf, index_t lv
2413 ) const {
2414 geo_debug_assert(is_simplicial_);
2415 geo_debug_assert(t < nb());
2416 geo_debug_assert(lf < 4);
2417 geo_debug_assert(lv < 3);
2418 return cell_corners_.vertex(
2419 4 * t + local_tet_facet_vertex_index(lf,lv)
2420 );
2421 }
2422
2437 index_t t, index_t v1, index_t v2, index_t v3
2438 ) const {
2439 geo_debug_assert(is_simplicial_);
2440 for(index_t lf = 0; lf < 4; ++lf) {
2441 index_t w1 = tet_facet_vertex(t, lf, 0);
2442 index_t w2 = tet_facet_vertex(t, lf, 1);
2443 index_t w3 = tet_facet_vertex(t, lf, 2);
2444 if(
2445 (v1 == w1 && v2 == w2 && v3 == w3) ||
2446 (v1 == w2 && v2 == w3 && v3 == w1) ||
2447 (v1 == w3 && v2 == w1 && v3 == w2)
2448 ) {
2449 return lf;
2450 }
2451 }
2452 return NO_FACET;
2453 }
2454
2464 geo_debug_assert(lf < 4);
2465 geo_debug_assert(lv < 3);
2466 return MeshCellDescriptors::tet_descriptor.facet_vertex[lf][lv];
2467 }
2468
2469 protected:
2470
2478 if(is_simplicial_) {
2479 is_simplicial_ = false;
2480 cell_ptr_.resize(nb()+1);
2481 cell_type_.assign(nb(), MESH_TET);
2482 for(index_t c=0; c<cell_ptr_.size(); ++c) {
2483 cell_ptr_[c] = 4*c;
2484 }
2485 }
2486 }
2487
2500 index_t c1, index_t f1, index_t c2, index_t f2
2501 ) const;
2502
2512 geo_debug_assert(c < nb());
2513 geo_debug_assert(v < vertices_.nb());
2514 for(index_t lv=0; lv<nb_vertices(c); ++lv) {
2515 if(vertex(c,lv) == v) {
2516 return lv;
2517 }
2518 }
2519 return NO_VERTEX;
2520 }
2521
2534 index_t c1, index_t c2, index_t f2
2535 ) const {
2536 for(index_t f1=0; f1<nb_facets(c1); ++f1) {
2537 if(facets_match(c1,f1,c2,f2)) {
2538 return f1;
2539 }
2540 }
2541 return NO_FACET;
2542 }
2543
2557 index_t c1, index_t lf1,
2558 index_t c2, index_t lf2
2559 ) const;
2560
2561
2576 index_t c1, index_t f1,
2577 index_t c2, index_t f2,
2578 index_t& e1, index_t& e2
2579 ) const;
2580
2600 index_t c1, index_t lf1,
2601 const std::vector< std::pair<index_t, index_t> >& matches
2602 );
2603
2609
2610 protected:
2611 MeshVertices& vertices_;
2612 MeshCellCornersStore& cell_corners_;
2613 MeshCellFacetsStore& cell_facets_;
2614 friend class Mesh;
2615 friend class GeogramIOHandler;
2616 };
2617
2618 /*************************************************************************/
2619
2628 MESH_NONE = 0,
2629 MESH_VERTICES = 1,
2630 MESH_FACETS = 2,
2631 MESH_EDGES = 4,
2632 MESH_CELLS = 8,
2633 MESH_ALL_ELEMENTS = 15,
2634 MESH_FACET_CORNERS = 16,
2635 MESH_CELL_CORNERS = 32,
2636 MESH_CELL_FACETS = 64,
2637 MESH_ALL_SUBELEMENTS = 65
2638 };
2639
2640 /*************************************************************************/
2641
2648 class GEOGRAM_API Mesh {
2649 public:
2650 MeshVertices vertices;
2651 MeshEdges edges;
2652 MeshFacets facets;
2653 MeshFacetCornersStore facet_corners;
2654 MeshCells cells;
2655 MeshCellCornersStore cell_corners;
2656 MeshCellFacetsStore cell_facets;
2657
2665 Mesh(index_t dimension=3, bool single_precision=false);
2666
2670 virtual ~Mesh();
2671
2682 void clear(bool keep_attributes=true, bool keep_memory=false);
2683
2687 void show_stats(const std::string& tag = "Mesh") const;
2688
2689
2698
2699
2710 void copy(
2711 const Mesh& rhs,
2712 bool copy_attributes=true,
2713 MeshElementsFlags what=MESH_ALL_ELEMENTS
2714 );
2715
2716
2721 std::string get_attributes() const;
2722
2729 std::string get_scalar_attributes() const;
2730
2737 std::string get_vector_attributes(index_t max_dim = 0) const;
2738
2744
2752
2760
2761
2769
2778 ) const;
2779
2787
2796 const std::string& name
2797 );
2798
2814 const std::string& full_attribute_name,
2815 MeshElementsFlags& where,
2816 std::string& attribute_name,
2817 index_t& component
2818 );
2819
2820 protected:
2829 const std::string& tag, const std::string& subelement_name,
2830 const MeshSubElementsStore& subelements
2831 ) const;
2832
2833 private:
2841 Mesh(const Mesh& rhs);
2842
2850 const Mesh& operator=(const Mesh& rhs);
2851 };
2852
2853 /*************************************************************************/
2854}
2855
2856#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:195
Generic mechanism for attributes.
Common include file, providing basic definitions. Should be included before anything else by all head...
Manages an attribute attached to a set of object.
Managers a set of attributes attached to an object.
Definition attributes.h:732
index_t size() const
Gets the size.
Definition attributes.h:767
Stores the cell corners of a mesh (low-level store)
Definition mesh.h:1696
void set_vertex(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:1715
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition mesh.h:1705
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:1728
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:1740
Stores the cell facets of a mesh (low-level store)
Definition mesh.h:1786
index_t adjacent_cell(index_t f) const
Gets a cell adjacent to a facet.
Definition mesh.h:1800
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:1835
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:1824
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:1812
Stores the cells of a mesh (low-level store)
Definition mesh.h:1485
index_t facet(index_t c, index_t lf) const
Gets a facet of a cell by local facet index.
Definition mesh.h:1631
bool are_simplices() const
Tests whether all the cells are tetrahedra.
Definition mesh.h:1496
static const CellDescriptor & cell_type_to_cell_descriptor(MeshCellType t)
Gets a descriptor by cell type.
Definition mesh.h:1538
const CellDescriptor & descriptor(index_t c) const
Gets the descriptor of a cell.
Definition mesh.h:1519
index_t corner(index_t c, index_t lv) const
Gets a corner of a cell by local vertex index.
Definition mesh.h:1583
index_t nb_facets(index_t c) const
Gets the number of facets of a cell.
Definition mesh.h:1598
index_t corners_end(index_t c) const
Gets the upper limit for iterating over the corners of a cell.
Definition mesh.h:1572
MeshCellType type(index_t c) const
Gets the type of a cell.
Definition mesh.h:1506
index_t facets_end(index_t c) const
Gets the upper limit for iterating over the facets of a cell.
Definition mesh.h:1620
index_t nb_corners(index_t c) const
Gets the number of corners of a cell.
Definition mesh.h:1550
index_t corners_begin(index_t c) const
Gets the first element for iterating over the corners of a cell.
Definition mesh.h:1561
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:1642
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:1609
The cells of a mesh.
Definition mesh.h:1882
index_t create_cells(index_t nb_cells, MeshCellType type)
Creates a contiguous chunk of cells of the same type.
Definition mesh.h:2043
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:1915
index_t create_pyramids(index_t nb_pyramids)
Creates a contiguous chunk of pyramids.
Definition mesh.h:2120
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:1926
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.
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:2281
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:2411
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:1987
range< no_iterator > corners(index_t c) const
Gets the corners of a cell.
Definition mesh.h:2016
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:2463
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:2206
index_t nb_vertices(index_t c) const
Gets the number of vertices of a cell.
Definition mesh.h:1895
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:1960
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:2244
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:2436
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:2477
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:1974
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:2511
index_t create_hexes(index_t nb_hexes)
Creates a contiguous chunk of hexahedra.
Definition mesh.h:2102
index_t create_tets(index_t nb_tets)
Creates a contiguous chunk of tetrahedra.
Definition mesh.h:2093
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:2005
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:1937
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:2111
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:2132
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:2164
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:1947
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.
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:2533
index_t vertex(index_t c, index_t lv) const
Gets a vertex of a cell by local vertex index.
Definition mesh.h:1905
The edges of a mesh.
Definition mesh.h:615
index_t vertex(index_t e, index_t lv) const
Gets the index of an edge vertex.
Definition mesh.h:626
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:662
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:689
index_t create_edge()
Creates a new edge.
Definition mesh.h:671
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:680
index_t * vertex_index_ptr(index_t c)
Gets a pointer to a vertex index by corner index.
Definition mesh.h:651
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:638
Base class for mesh elements.
Definition mesh.h:232
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:291
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:856
index_t * vertex_index_ptr(index_t c)
Gets a pointer to the vertex that a corner is incident to.
Definition mesh.h:952
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:888
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:901
index_t adjacent_facet(index_t c) const
Gets the facet that a corner is adjacent to.
Definition mesh.h:876
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:964
void set_vertex_no_check(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:928
index_t vertex(index_t c) const
Gets the vertex that a corner is incident to.
Definition mesh.h:865
void set_adjacent_facet(index_t c, index_t f)
Sets the facet that a corner is adjacent to.
Definition mesh.h:939
void set_vertex(index_t c, index_t v)
Sets the vertex that a corner is incident to.
Definition mesh.h:912
Stores the facets of a mesh (low-level store)
Definition mesh.h:742
index_t corner(index_t f, index_t lv) const
Gets a corner by facet and local vertex index.
Definition mesh.h:785
index_t corners_end(index_t f) const
Gets the upper limit for iterating over the corners of a facet.
Definition mesh.h:763
index_t nb_corners(index_t f) const
Gets the number of corners in a facet.
Definition mesh.h:773
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:808
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:798
index_t corners_begin(index_t f) const
Gets the first element for iterating over the corners of a facet.
Definition mesh.h:752
The facets of a mesh.
Definition mesh.h:1017
index_t create_triangle(index_t v1, index_t v2, index_t v3)
Creates a triangle.
Definition mesh.h:1220
range< no_iterator > corners(index_t f) const
Gets the corners of a facet.
Definition mesh.h:1367
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:1238
index_t create_polygon(const vector< index_t > &vertices)
Creates a polygonal facet.
Definition mesh.h:1300
void is_not_simplicial()
Indicates that the stored elements are no longer only triangles.
Definition mesh.h:1394
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:1043
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:1032
void is_simplicial()
Indicates that the stored elements are only triangles.
Definition mesh.h:1380
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:1256
index_t create_polygon(index_t nb_vertices, const index_t *vertices)
Creates a polygonal facet.
Definition mesh.h:1278
void set_vertex(index_t f, index_t lv, index_t v)
Sets a vertex by facet and local vertex index.
Definition mesh.h:1054
index_t find_common_vertex(index_t f1, index_t f2) const
finds a common vertex shared by two facets
Definition mesh.h:1080
void pop() override
Removes the last element.
index_t find_vertex(index_t f, index_t v) const
Gets the local index of a vertex in a facet.
Definition mesh.h:1065
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:1108
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:1148
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:1211
index_t create_facets(index_t nb_facets, index_t nb_vertices_per_polygon)
Creates a contiguous chunk of facets.
Definition mesh.h:1172
index_t adjacent(index_t f, index_t le) const
Gets an adjacent facet by facet and local edge index.
Definition mesh.h:1097
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:1124
index_t create_triangles(index_t nb_triangles)
Creates a contiguous chunk of triangles.
Definition mesh.h:1202
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:1135
Base class for mesh sub-element storage.
Definition mesh.h:70
virtual ~MeshSubElementsStore()
MeshElementStore destructor.
AttributesManager & attributes() const
Gets the attributes manager.
Definition mesh.h:100
no_iterator begin() const
Used by range-based for.
Definition mesh.h:108
MeshSubElementsStore(Mesh &mesh)
Constructs a new MeshSubElementStore.
index_t create_sub_element()
Creates attributes for a sub-element.
Definition mesh.h:169
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:148
index_t nb() const
Gets the number of (sub-)elements.
Definition mesh.h:89
void copy(const MeshSubElementsStore &rhs, bool copy_attributes=true)
Copies a MeshSubElementsStore into this one.
Definition mesh.h:203
no_iterator end() const
Used by range-based for.
Definition mesh.h:116
void adjust_store()
Makes the size of the store tightly match the number of the elements.
Definition mesh.h:190
virtual void resize_store(index_t new_size)
Resizes this MeshSubElementsStore.
The vertices of a mesh.
Definition mesh.h:312
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.
index_t create_vertex(const double *coords)
Creates a new vertex.
Definition mesh.h:342
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:499
const double * point_ptr(index_t v) const
Gets a point.
Definition mesh.h:444
float * single_precision_point_ptr(index_t v)
Gets a (single-precision) point.
Definition mesh.h:512
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:429
void set_double_precision()
Sets double precision mode.
vec3 & point(index_t v)
Gets a point.
Definition mesh.h:471
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
const vec3 & point(index_t v) const
Gets a point.
Definition mesh.h:485
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:408
bool single_precision() const
Tests whether vertices are stored in single-precision mode.
Definition mesh.h:397
index_t dimension() const
Gets the dimension of the vertices.
Definition mesh.h:416
index_t create_vertices(index_t nb)
Creates a contiguous chunk of vertices.
Definition mesh.h:364
void set_single_precision()
Sets single precision mode.
double * point_ptr(index_t v)
Gets a point.
Definition mesh.h:457
index_t create_vertex()
Creates a new vertex.
Definition mesh.h:333
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:2648
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:2627
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.
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.
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 for range-based for construct.
Definition range.h:58
A generic range bounded by two "non-iterators".
Definition range.h:90
Vector with aligned memory allocation.
Definition memory.h:623
T * data()
Gets a pointer to the array of elements.
Definition memory.h:762
index_t size() const
Gets the number of elements.
Definition memory.h:662
Geometric functions in 2d and 3d.
void copy(void *to, const void *from, size_t size)
Copies a memory block.
Definition memory.h:117
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:90
Global Vorpaline namespace.
Definition algorithm.h:64
geo_index_t index_t
The type for storing and manipulating indices.
Definition numeric.h:287
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
Definition numeric.h:321
C++-20 like helpers for manipulating ranges of integers.
Lookup tables that describe the combinatorics of each cell type.
Definition mesh.h:1430
index_t nb_vertices_in_facet[6]
Definition mesh.h:1438
index_t facet_vertex[6][4]
Definition mesh.h:1443
index_t nb_vertices
Definition mesh.h:1432
index_t nb_facets
Definition mesh.h:1435
index_t edge_adjacent_facet[12][2]
Definition mesh.h:1457
index_t nb_edges
Definition mesh.h:1447
index_t edge_vertex[12][2]
Definition mesh.h:1452