40#ifndef GEOGRAM_MESH_MESH
41#define GEOGRAM_MESH_MESH
46#include <geogram/basic/vector_attribute.h>
54#define MESH_NO_SYNTAXIC_SUGAR
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;
141 bool keep_attributes,
bool keep_memory =
false
159 resize_store(nb + nb_to_reserve);
170 if(nb_ + nb > attributes_.size()) {
173 new_capacity = std::max(
index_t(16),attributes_.capacity());
174 while(new_capacity < nb_ + nb) {
178 attributes_.reserve(new_capacity);
181 attributes_.resize(nb_);
192 if(attributes_.capacity() < nb_) {
194 std::max(
index_t(16),attributes_.capacity()*2);
195 attributes_.reserve(new_capacity);
197 attributes_.resize(nb_);
211 attributes_.resize(nb_);
225 bool copy_attributes =
true
228 if(copy_attributes) {
229 attributes_.copy(rhs.attributes_);
231 attributes_.clear(
false,
false);
232 attributes_.resize(rhs.attributes_.
size());
268 bool remove_isolated_vertices=
true
295 bool keep_attributes=
true,
bool keep_memory=
false
324 class MeshFacetCornersStore;
325 class MeshCellCornersStore;
354 return MeshSubElementsStore::create_sub_element();
369 coords < point_ptr(0) ||
370 coords >= point_ptr(0) + nb() * dimension()
372 index_t result = create_vertex();
373 for(
index_t c=0; c<dimension(); ++c) {
374 point_ptr(result)[c] = coords[c];
389 return create_vertex(p.
data());
398 return MeshSubElementsStore::create_sub_elements(nb);
402 bool keep_attributes=
true,
bool keep_memory=
false
431 return point_fp32_.is_bound();
442 return point_.is_bound();
452 point_fp32_.dimension() :
463 if(single_precision()) {
464 point_fp32_.redim(dim);
480 return &point_[v*point_.dimension()];
493 return &point_[v*point_.dimension()];
508 return Memory::pointer_as_reference<vecng<DIM,double>>(
509 &point_[v*point_.dimension()]
526 return Memory::pointer_as_reference<vecng<DIM,double>>(
527 &point_[v*point_.dimension()]
541 return &point_fp32_[v*point_fp32_.dimension()];
554 return &point_fp32_[v*point_fp32_.dimension()];
568 return point_.get_vector();
579 return point_.get_vector();
610#ifndef MESH_NO_SYNTAXIC_SUGAR
616 template <index_t DIM = 3>
auto points()
const {
620 [
this](
index_t v)->
const vecn& {
622 return Memory::pointer_as_reference<vecn>(point_ptr(v));
632 template <index_t DIM = 3>
auto points() {
638 return Memory::pointer_as_reference<vecn>(point_ptr(v));
649 bool keep_attributes,
bool keep_memory =
false
654 void bind_point_attribute(
index_t dim,
bool single_precision=
false);
656 void copy(
const MeshVertices& rhs,
bool copy_attributes=
true) {
658 if(point_fp32_.is_bound()) {
659 point_fp32_.destroy();
661 if(point_.is_bound()) {
664 MeshSubElementsStore::copy(rhs, copy_attributes);
666 point_fp32_.bind_if_is_defined(attributes(),
"point_fp32");
667 if(!point_fp32_.is_bound()) {
668 point_fp32_.create_vector_attribute(
669 attributes(),
"point_fp32", dim
673 point_.bind_if_is_defined(attributes(),
"point");
674 if(!point_.is_bound()) {
675 point_.create_vector_attribute(
676 attributes(),
"point", dim
682 if(!copy_attributes) {
685 single_precision_point_ptr(0),
700 MeshFacetCornersStore& facet_corners_;
701 MeshCellCornersStore& cell_corners_;
702 Attribute<double> point_;
703 Attribute<float> point_fp32_;
706 friend class GeogramIOHandler;
730 return edge_vertex_[2*e+lv];
742 edge_vertex_[2*e+lv] = v;
754 return &(edge_vertex_[c]);
765 return &(edge_vertex_[c]);
773 return create_sub_element();
782 return create_sub_elements(nb);
791 index_t result = create_edge();
792 set_vertex(result,0,v1);
793 set_vertex(result,1,v2);
804 bool keep_attributes=
true,
bool keep_memory=
false
817 bool keep_attributes,
bool keep_memory =
false
823 edge_vertex_.push_back(NO_VERTEX);
824 edge_vertex_.push_back(NO_VERTEX);
825 return MeshSubElementsStore::create_sub_element();
829 edge_vertex_.resize(2*(nb()+nb_in),NO_VERTEX);
830 return MeshSubElementsStore::create_sub_elements(nb_in);
833 void copy(
const MeshEdges& rhs,
bool copy_attributes=
true) {
834 MeshSubElementsStore::copy(rhs, copy_attributes);
835 edge_vertex_ = rhs.edge_vertex_;
838 vector<index_t> edge_vertex_;
840 friend class GeogramIOHandler;
861 return (is_simplicial_ ? 3*f : facet_ptr_[f]);
872 return (is_simplicial_ ? 3*(f+1): facet_ptr_[f+1]);
882 return (is_simplicial_ ? 3 : facet_ptr_[f+1] - facet_ptr_[f]);
895 return corners_begin(f)+lv;
906 return is_simplicial_;
918 return &facet_ptr_[f];
930 return &facet_ptr_[f];
936 bool keep_attributes,
bool keep_memory =
false
942 if(!is_simplicial_) {
943 facet_ptr_.push_back(NO_CORNER);
945 return MeshSubElementsStore::create_sub_element();
948 index_t create_sub_elements(index_t nb) {
949 if(!is_simplicial_) {
950 for(index_t i=0; i<nb; ++i) {
951 facet_ptr_.push_back(NO_CORNER);
954 return MeshSubElementsStore::create_sub_elements(nb);
957 void copy(
const MeshFacetsStore& rhs,
bool copy_attributes=
true) {
958 MeshSubElementsStore::copy(rhs,copy_attributes);
959 is_simplicial_ = rhs.is_simplicial_;
960 facet_ptr_ = rhs.facet_ptr_;
965 vector<index_t> facet_ptr_;
967 friend class GeogramIOHandler;
987 return corner_vertex_[c];
998 return corner_adjacent_facet_[c];
1010 return &corner_adjacent_facet_[c];
1023 return &corner_adjacent_facet_[c];
1035 corner_vertex_[c] = v;
1050 corner_vertex_[c] = v;
1062 corner_adjacent_facet_[c] = f;
1074 return &(corner_vertex_[c]);
1086 return &(corner_vertex_[c]);
1097 return corner_vertex_;
1108 return vertices_.point<DIM>(vertex(c));
1122 return vertices_.point(vertex(c));
1127 bool keep_attributes,
bool keep_memory =
false
1133 corner_vertex_.push_back(v);
1134 corner_adjacent_facet_.push_back(f);
1135 return MeshSubElementsStore::create_sub_element();
1140 corner_vertex_.push_back(NO_VERTEX);
1142 for(index_t i=0; i<nb; ++i) {
1143 corner_adjacent_facet_.push_back(NO_FACET);
1145 return MeshSubElementsStore::create_sub_elements(nb);
1149 const MeshFacetCornersStore& rhs,
bool copy_attributes=
true
1151 MeshSubElementsStore::copy(rhs, copy_attributes);
1152 corner_vertex_ = rhs.corner_vertex_;
1153 corner_adjacent_facet_ = rhs.corner_adjacent_facet_;
1157 MeshVertices& vertices_;
1158 MeshFacetsStore& facets_;
1159 vector<index_t> corner_vertex_;
1160 vector<index_t> corner_adjacent_facet_;
1162 friend class MeshFacets;
1164 friend class GeogramIOHandler;
1189 return nb_corners(f);
1200 return facet_corners_.vertex(corner(f,lv));
1215 return vertices_.point<DIM>(vertex(f,lv));
1229 return vertices_.point<DIM>(vertex(f,lv));
1240 facet_corners_.set_vertex(corner(f,lv),v);
1251 for(
index_t lv=0; lv<nb_vertices(f); ++lv) {
1252 if(vertex(f,lv) == v) {
1266 for(
index_t lv=0; lv<nb_vertices(f1); ++lv) {
1268 if(find_vertex(f2,v) != NO_VERTEX) {
1283 return facet_corners_.adjacent_facet(corner(f,le));
1294 for(
index_t le=0; le<nb_vertices(f); ++le) {
1295 if(adjacent(f,le) == f2) {
1310 facet_corners_.set_adjacent_facet(corner(f,le),f2);
1323 return c + 1 == corners_end(f) ? corners_begin(f) : c + 1;
1336 return c == corners_begin(f) ? corners_end(f) - 1 : c - 1;
1347 for(
index_t c1 = corners_begin(f); c1 != corners_end(f); ++c1) {
1348 index_t c2 = next_corner_around_facet(f,c1);
1350 facet_corners_.vertex(c1) == v1 &&
1351 facet_corners_.vertex(c2) == v2
1353 return c1 - corners_begin(f);
1361 bool remove_isolated_vertices=
true
1367 bool keep_attributes=
true,
bool keep_memory=
false
1380 if(nb_vertices_per_polygon != 3) {
1381 is_not_simplicial();
1385 index_t co = facet_corners_.nb();
1386 facet_corners_.create_sub_elements(
1387 nb_facets*nb_vertices_per_polygon
1389 index_t result = create_sub_elements(nb_facets);
1391 if(!is_simplicial_) {
1392 for(
index_t f=first_facet; f<=first_facet+nb_facets; ++f) {
1394 co += nb_vertices_per_polygon;
1408 facet_corners_.reserve_store(nb_to_reserve*3);
1409 this->reserve_store(nb_to_reserve);
1418 return create_facets(nb_triangles, 3);
1427 return create_facets(nb_quads, 4);
1439 facet_corners_.create_sub_element(v1);
1440 facet_corners_.create_sub_element(v2);
1441 facet_corners_.create_sub_element(v3);
1442 index_t result = create_sub_element();
1443 if(!is_simplicial_) {
1444 facet_ptr_[result+1] = facet_corners_.nb();
1457 is_not_simplicial();
1458 facet_corners_.create_sub_element(v1);
1459 facet_corners_.create_sub_element(v2);
1460 facet_corners_.create_sub_element(v3);
1461 facet_corners_.create_sub_element(v4);
1462 index_t result = create_sub_element();
1463 facet_ptr_[result+1] = facet_corners_.nb();
1475 if(nb_vertices != 3) {
1476 is_not_simplicial();
1478 for(
index_t i=0; i<nb_vertices; ++i) {
1479 facet_corners_.create_sub_element(NO_VERTEX);
1481 index_t result = create_sub_element();
1482 if(!is_simplicial_) {
1483 facet_ptr_[result+1] = facet_corners_.nb();
1497 if(nb_vertices != 3) {
1498 is_not_simplicial();
1500 for(
index_t i=0; i<nb_vertices; ++i) {
1501 facet_corners_.create_sub_element(vertices[i]);
1503 index_t result = create_sub_element();
1504 if(!is_simplicial_) {
1505 facet_ptr_[result+1] = facet_corners_.nb();
1519 return create_polygon(vertices.
size(), vertices.
data());
1582 void assign_triangle_mesh(
1602#ifndef MESH_NO_SYNTAXIC_SUGAR
1613 return facet_corners_.vertex(c);
1629 return facet_corners_.adjacent_facet(c);
1644 corners(f), [
this](
index_t c)->
const vecn& {
1645 index_t v = facet_corners_.vertex(c);
1646 return vertices_.point<DIM>(v);
1661 corners(f), [
this](
index_t c)->vecn& {
1662 index_t v = facet_corners_.vertex(c);
1663 return vertices_.point<DIM>(v);
1676 index_t v0 = facet_corners_.vertex(corners_begin(f));
1682 [
this,v0](
index_t c)->std::tuple<index_t, index_t, index_t> {
1683 return std::make_tuple(
1685 facet_corners_.vertex(c),
1686 facet_corners_.vertex(c+1)
1705 [
this](std::tuple<index_t, index_t, index_t> T)
1706 ->std::tuple<const vecn&, const vecn&, const vecn&> {
1707 return std::tuple<const vecn&, const vecn&, const vecn&>(
1708 vertices_.point<DIM>(std::get<0>(T)),
1709 vertices_.point<DIM>(std::get<1>(T)),
1710 vertices_.point<DIM>(std::get<2>(T))
1729 [
this](std::tuple<index_t, index_t, index_t> T)
1730 ->std::tuple<vecn&, vecn&, vecn&> {
1731 return std::tuple<vecn&, vecn&, vecn&>(
1732 vertices_.point(std::get<0>(T)),
1733 vertices_.point(std::get<1>(T)),
1734 vertices_.point(std::get<2>(T))
1748 if(!is_simplicial_) {
1749 is_simplicial_ =
true;
1750 facet_ptr_.resize(1);
1762 if(is_simplicial_) {
1763 is_simplicial_ =
false;
1764 facet_ptr_.resize(nb()+1);
1765 for(
index_t f=0; f<facet_ptr_.size(); ++f) {
1766 facet_ptr_[f] = 3*f;
1775 friend class GeogramIOHandler;
1789 MESH_NB_CELL_TYPES = 5
1834 namespace MeshCellDescriptors {
1864 return is_simplicial_;
1875 return is_simplicial_ ? MESH_TET : MeshCellType(cell_type_[c]);
1908 return descriptor(c).nb_vertices;
1919 return is_simplicial_ ? 4*c : cell_ptr_[c];
1930 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_corners(c);
1943#ifndef GEO_OS_WINDOWS
1946 return corners_begin(c) + lv;
1956 return descriptor(c).nb_facets;
1967 return is_simplicial_ ? 4*c : cell_ptr_[c];
1978 return is_simplicial_ ? 4*(c+1) : cell_ptr_[c] + nb_facets(c);
1990 return facets_begin(c) + lf;
1999 return descriptor(c).nb_edges;
2010 return &cell_ptr_[c];
2021 return &cell_ptr_[c];
2032 return &cell_type_[c];
2043 return &cell_type_[c];
2049 bool keep_attributes,
bool keep_memory =
false
2054 index_t create_sub_element(MeshCellType type) {
2055 if(!is_simplicial_) {
2056 cell_ptr_.push_back(NO_CORNER);
2059 return MeshSubElementsStore::create_sub_element();
2062 index_t create_sub_elements(index_t nb, MeshCellType type) {
2063 if(!is_simplicial_) {
2064 for(index_t i=0; i<nb; ++i) {
2065 cell_ptr_.push_back(NO_CORNER);
2066 cell_type_.push_back(Numeric::uint8(type));
2069 return MeshSubElementsStore::create_sub_elements(nb);
2073 const MeshCellsStore& rhs,
bool copy_attributes=
true
2075 MeshSubElementsStore::copy(rhs, copy_attributes);
2076 is_simplicial_ = rhs.is_simplicial_;
2077 cell_type_ = rhs.cell_type_;
2078 cell_ptr_ = rhs.cell_ptr_;
2082 bool is_simplicial_;
2083 vector<Numeric::uint8> cell_type_;
2084 vector<index_t> cell_ptr_;
2088 friend class GeogramIOHandler;
2108 return corner_vertex_[c];
2119 corner_vertex_[c] = v;
2131 return &(corner_vertex_[c]);
2143 return &(corner_vertex_[c]);
2154 return vertices_.point<DIM>(vertex(c));
2168 return vertices_.point(vertex(c));
2173 bool keep_attributes,
bool keep_memory =
false
2179 corner_vertex_.push_back(v);
2180 return MeshSubElementsStore::create_sub_element();
2185 corner_vertex_.push_back(NO_VERTEX);
2187 return MeshSubElementsStore::create_sub_elements(nb);
2191 const MeshCellCornersStore& rhs,
bool copy_attributes=
true
2193 MeshSubElementsStore::copy(rhs, copy_attributes);
2194 corner_vertex_ = rhs.corner_vertex_;
2198 MeshVertices& vertices_;
2199 vector<index_t> corner_vertex_;
2201 friend class MeshCells;
2203 friend class GeogramIOHandler;
2228 return adjacent_cell_[f];
2241 adjacent_cell_[f] = c;
2252 return &adjacent_cell_[f];
2263 return &adjacent_cell_[f];
2268 bool keep_attributes,
bool keep_memory =
false
2274 adjacent_cell_.push_back(c);
2275 return MeshSubElementsStore::create_sub_element();
2280 adjacent_cell_.push_back(NO_CELL);
2282 return MeshSubElementsStore::create_sub_elements(nb);
2286 const MeshCellFacetsStore& rhs,
bool copy_attributes=
true
2288 MeshSubElementsStore::copy(rhs, copy_attributes);
2289 adjacent_cell_ = rhs.adjacent_cell_;
2293 MeshVertices& vertices_;
2294 MeshCellsStore& cells_;
2295 vector<index_t> adjacent_cell_;
2297 friend class MeshCells;
2299 friend class GeogramIOHandler;
2322 return nb_corners(c);
2332 return cell_corners_.vertex(corner(c,lv));
2342 cell_corners_.set_vertex(corner(c,lv),v);
2356 return vertices_.point<DIM>(vertex(c,lv));
2370 return vertices_.point<DIM>(vertex(c,lv));
2381 return cell_facets_.adjacent_cell(facet(c,lf));
2392 cell_facets_.set_adjacent_cell(facet(c,lf),c2);
2403 return descriptor(c).nb_vertices_in_facet[lf];
2416 return cell_corners_.vertex(
2417 corner(c, descriptor(c).facet_vertex[lf][lv])
2430 return corner(c, descriptor(c).facet_vertex[lf][lc]);
2444 return cell_corners_.vertex(
2445 corner(c,descriptor(c).edge_vertex[le][lv])
2462 return descriptor(c).edge_adjacent_facet[le][lf];
2491#ifndef MESH_NO_SYNTAXIC_SUGAR
2503 corners(cell), [
this](
index_t c)->
const vecn& {
2504 index_t v = cell_corners_.vertex(c);
2505 return vertices_.point<DIM>(v);
2520 corners(cell), [
this](
index_t c)->vecn& {
2521 index_t v = cell_corners_.vertex(c);
2522 return vertices_.point<DIM>(v);
2538 return cell_facets_.adjacent_cell(f);
2546 bool keep_attributes=
true,
bool keep_memory=
false
2551 bool remove_isolated_vertices=
true
2571 if(type != MESH_TET) {
2572 is_not_simplicial();
2583 index_t co = cell_corners_.nb();
2585 cell_corners_.create_sub_elements(
2589 cell_facets_.create_sub_elements(
2593 index_t result = create_sub_elements(nb_cells, type);
2595 if(!is_simplicial_) {
2596 for(
index_t c=first_cell; c<=first_cell+nb_cells; ++c) {
2615 return create_cells(nb_tets, MESH_TET);
2624 return create_cells(nb_hexes, MESH_HEX);
2633 return create_cells(nb_prisms, MESH_PRISM);
2642 return create_cells(nb_pyramids, MESH_PYRAMID);
2660 cell_corners_.create_sub_element(v1);
2661 cell_corners_.create_sub_element(v2);
2662 cell_corners_.create_sub_element(v3);
2663 cell_corners_.create_sub_element(v4);
2664 cell_facets_.create_sub_element(adj1);
2665 cell_facets_.create_sub_element(adj2);
2666 cell_facets_.create_sub_element(adj3);
2667 cell_facets_.create_sub_element(adj4);
2668 index_t result = create_sub_element(MESH_TET);
2669 if(!is_simplicial_) {
2670 cell_ptr_[nb()] = cell_corners_.nb();
2695 is_not_simplicial();
2696 cell_corners_.create_sub_element(v1);
2697 cell_corners_.create_sub_element(v2);
2698 cell_corners_.create_sub_element(v3);
2699 cell_corners_.create_sub_element(v4);
2700 cell_corners_.create_sub_element(v5);
2701 cell_corners_.create_sub_element(v6);
2702 cell_corners_.create_sub_element(v7);
2703 cell_corners_.create_sub_element(v8);
2704 cell_facets_.create_sub_element(adj1);
2705 cell_facets_.create_sub_element(adj2);
2706 cell_facets_.create_sub_element(adj3);
2707 cell_facets_.create_sub_element(adj4);
2708 cell_facets_.create_sub_element(adj5);
2709 cell_facets_.create_sub_element(adj6);
2710 cell_facets_.create_sub_element(NO_CELL);
2711 cell_facets_.create_sub_element(NO_CELL);
2712 index_t result = create_sub_element(MESH_HEX);
2713 cell_ptr_[nb()] = cell_corners_.nb();
2737 is_not_simplicial();
2738 cell_corners_.create_sub_element(v1);
2739 cell_corners_.create_sub_element(v2);
2740 cell_corners_.create_sub_element(v3);
2741 cell_corners_.create_sub_element(v4);
2742 cell_corners_.create_sub_element(v5);
2743 cell_corners_.create_sub_element(v6);
2744 cell_facets_.create_sub_element(adj1);
2745 cell_facets_.create_sub_element(adj2);
2746 cell_facets_.create_sub_element(adj3);
2747 cell_facets_.create_sub_element(adj4);
2748 cell_facets_.create_sub_element(adj5);
2749 cell_facets_.create_sub_element(NO_CELL);
2750 index_t result = create_sub_element(MESH_PRISM);
2751 cell_ptr_[nb()] = cell_corners_.nb();
2773 is_not_simplicial();
2774 cell_corners_.create_sub_element(v1);
2775 cell_corners_.create_sub_element(v2);
2776 cell_corners_.create_sub_element(v3);
2777 cell_corners_.create_sub_element(v4);
2778 cell_corners_.create_sub_element(v5);
2779 cell_facets_.create_sub_element(adj1);
2780 cell_facets_.create_sub_element(adj2);
2781 cell_facets_.create_sub_element(adj3);
2782 cell_facets_.create_sub_element(adj4);
2783 cell_facets_.create_sub_element(adj5);
2784 index_t result = create_sub_element(MESH_PYRAMID);
2785 cell_ptr_[nb()] = cell_corners_.nb();
2808 is_not_simplicial();
2809 cell_corners_.create_sub_element(v1);
2810 cell_corners_.create_sub_element(v2);
2811 cell_corners_.create_sub_element(v3);
2812 cell_corners_.create_sub_element(v4);
2813 cell_facets_.create_sub_element(adj1);
2814 cell_facets_.create_sub_element(adj2);
2815 cell_facets_.create_sub_element(adj3);
2816 cell_facets_.create_sub_element(NO_CELL);
2817 index_t result = create_sub_element(MESH_CONNECTOR);
2818 cell_ptr_[nb()] = cell_corners_.nb();
2834 bool remove_trivial_slivers =
true,
bool verbose_if_OK=
false
2888 return cell_facets_.adjacent_cell_[4*t+lf];
2895 for(
index_t lf=0; lf<4; ++lf) {
2896 if(cell_facets_.adjacent_cell_[4*t+lf] == t2) {
2903 index_t tet_vertex(index_t t, index_t lv)
const {
2907 return cell_corners_.corner_vertex_[4*t+lv];
2910 index_t find_tet_vertex(index_t t, index_t v)
const {
2914 for(index_t lv=0; lv<4; ++lv) {
2915 if(cell_corners_.corner_vertex_[4*t+lv] == v) {
2939 return cell_corners_.vertex(
2940 4 * t + local_tet_facet_vertex_index(lf,lv)
2961 for(
index_t lf = 0; lf < 4; ++lf) {
2962 index_t w1 = tet_facet_vertex(t, lf, 0);
2963 index_t w2 = tet_facet_vertex(t, lf, 1);
2964 index_t w3 = tet_facet_vertex(t, lf, 2);
2966 (v1 == w1 && v2 == w2 && v3 == w3) ||
2967 (v1 == w2 && v2 == w3 && v3 == w1) ||
2968 (v1 == w3 && v2 == w1 && v3 == w2)
2987 return MeshCellDescriptors::tet_descriptor.facet_vertex[lf][lv];
2999 if(is_simplicial_) {
3000 is_simplicial_ =
false;
3001 cell_ptr_.resize(nb()+1);
3002 cell_type_.assign(nb(), MESH_TET);
3003 for(
index_t c=0; c<cell_ptr_.size(); ++c) {
3035 for(
index_t lv=0; lv<nb_vertices(c); ++lv) {
3036 if(vertex(c,lv) == v) {
3057 for(
index_t f1=0; f1<nb_facets(c1); ++f1) {
3058 if(facets_match(c1,f1,c2,f2)) {
3122 const std::vector< std::pair<index_t, index_t> >& matches
3136 friend class GeogramIOHandler;
3154 MESH_ALL_ELEMENTS = 15,
3155 MESH_FACET_CORNERS = 16,
3156 MESH_CELL_CORNERS = 32,
3157 MESH_CELL_FACETS = 64,
3158 MESH_ALL_SUBELEMENTS = 65
3203 void clear(
bool keep_attributes=
true,
bool keep_memory=
false);
3235 bool copy_attributes=
true,
3249 bool load(
const std::string& filename);
3258 bool save(
const std::string& filename)
const;
3339 const std::string& name
3357 const std::string& full_attribute_name,
3359 std::string& attribute_name,
3372 const std::string& tag,
const std::string& subelement_name,
#define geo_debug_assert(x)
Verifies that a condition is met.
Generic mechanism for attributes.
Manages an attribute attached to a set of object.
Manages a set of attributes attached to an object.
index_t size() const
Gets the size.
Stores the cell facets of a mesh (low-level store)
index_t adjacent_cell(index_t f) const
Gets a cell adjacent to a facet.
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.
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.
MeshCellFacetsStore(Mesh &mesh)
MeshCellFacetsStore constructor.
void set_adjacent_cell(index_t f, index_t c)
Sets a cell adjacent to a facet.
Stores the cells of a mesh (low-level store)
index_t facet(index_t c, index_t lf) const
Gets a facet of a cell by local facet index.
bool are_simplices() const
Tests whether all the cells are tetrahedra.
static const CellDescriptor & cell_type_to_cell_descriptor(MeshCellType t)
Gets a descriptor by cell type.
const CellDescriptor & descriptor(index_t c) const
Gets the descriptor of a cell.
index_t corner(index_t c, index_t lv) const
Gets a corner of a cell by local vertex index.
index_t nb_facets(index_t c) const
Gets the number of facets of a cell.
Numeric::uint8 * cell_type_ptr(index_t c)
Gets a pointer to a cell type by cell index.
index_t corners_end(index_t c) const
Gets the upper limit for iterating over the corners of a cell.
MeshCellType type(index_t c) const
Gets the type of a cell.
index_t facets_end(index_t c) const
Gets the upper limit for iterating over the facets of a cell.
const index_t * cell_ptr_ptr(index_t c) const
Gets a pointer to a cell pointer index by cell index.
const Numeric::uint8 * cell_type_ptr(index_t c) const
Gets a pointer to a cell type by cell index.
index_t nb_corners(index_t c) const
Gets the number of corners of a cell.
index_t corners_begin(index_t c) const
Gets the first element for iterating over the corners of a cell.
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
index_t * cell_ptr_ptr(index_t c)
Gets a pointer to a cell pointer index by cell index.
index_t nb_edges(index_t c) const
Gets the number of edges in a cell.
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.
index_t create_cells(index_t nb_cells, MeshCellType type)
Creates a contiguous chunk of cells of the same type.
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.
index_t create_pyramids(index_t nb_pyramids)
Creates a contiguous chunk of pyramids.
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.
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.
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.
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.
index_range corners(index_t c) const
Gets the corners of a cell.
auto points(index_t cell)
Gets the points associated with the vertices of a cell.
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.
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.
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.
index_t nb_vertices(index_t c) const
Gets the number of vertices of a cell.
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.
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.
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.
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.
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.
index_t find_cell_vertex(index_t c, index_t v) const
Finds the local index of a vertex in a cell.
index_t create_hexes(index_t nb_hexes)
Creates a contiguous chunk of hexahedra.
index_t create_tets(index_t nb_tets)
Creates a contiguous chunk of tetrahedra.
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.
auto adjacent(index_t c) const
Gets the cells adjacent to a given cell.
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.
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.
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.
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.
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.
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_range facets(index_t c) const
Gets the facets of a cell.
auto points(index_t cell) const
Gets the points associated with the vertices of a cell.
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.
const vecng< DIM, double > & point(index_t c, index_t lv) const
Gets a point by cell and local vertex index.
index_t vertex(index_t c, index_t lv) const
Gets a vertex of a cell by local vertex index.
index_t vertex(index_t e, index_t lv) const
Gets the index of an edge vertex.
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
void flip(index_t e)
Swaps both extremities of an edge.
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.
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.
index_t create_edge()
Creates a new edge.
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.
index_t * vertex_index_ptr(index_t c)
Gets a pointer to a vertex index by corner index.
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.
Base class for mesh elements.
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.
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 facets of a mesh (low-level store)
index_t corner(index_t f, index_t lv) const
Gets a corner by facet and local vertex index.
index_t corners_end(index_t f) const
Gets the upper limit for iterating over the corners of a facet.
index_t nb_corners(index_t f) const
Gets the number of corners in a facet.
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.
void clear_store(bool keep_attributes, bool keep_memory=false) override
Removes all the elements and attributes.
index_t * corners_begin_ptr(index_t f)
Gets a pointer to the first element for iterating over the corners of a facet.
void resize_store(index_t new_size) override
Resizes this MeshSubElementsStore.
bool are_simplices() const
Tests whether all the facets are triangles.
index_t corners_begin(index_t f) const
Gets the first element for iterating over the corners of a facet.
index_t create_triangle(index_t v1, index_t v2, index_t v3)
Creates a triangle.
auto triangle_points(index_t f)
Decomposes a facet into triangles.
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.
auto triangles(index_t f) const
Decomposes a facet into triangles.
index_t create_polygon(const vector< index_t > &vertices)
Creates a polygonal facet.
void is_not_simplicial()
Indicates that the stored elements are no longer only triangles.
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.
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.
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.
void is_simplicial()
Indicates that the stored elements are only triangles.
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.
index_t create_polygon(index_t nb_vertices, const index_t *vertices)
Creates a polygonal facet.
void set_vertex(index_t f, index_t lv, index_t v)
Sets a vertex by facet and local vertex index.
auto vertices(index_t f) const
Gets the vertices of a facet.
index_t find_common_vertex(index_t f1, index_t f2) const
finds a common vertex shared by two facets
index_range corners(index_t f) const
Gets the corners of a facet.
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.
auto adjacent(index_t f) const
Gets the facets adjacent to a given facet.
index_t find_vertex(index_t f, index_t v) const
Gets the local index of a vertex in a facet.
vecng< DIM, double > & point(index_t f, index_t lv)
Gets a point by facet and local vertex index.
index_t find_adjacent(index_t f, index_t f2) const
Gets the local index of a facet adjacent to another one.
index_t prev_corner_around_facet(index_t f, index_t c) const
Gets the predecessor of a corner around a facet.
auto points(index_t f)
Gets the points associated with the vertices of a facet.
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.
index_t create_facets(index_t nb_facets, index_t nb_vertices_per_polygon)
Creates a contiguous chunk of facets.
const vecng< DIM, double > & point(index_t f, index_t lv) const
Gets a point by facet and local vertex index.
index_t adjacent(index_t f, index_t le) const
Gets an adjacent facet by facet and local edge index.
auto points(index_t f) const
Gets the points associated with the vertices of a facet.
void set_adjacent(index_t f, index_t le, index_t f2)
Sets an adjacent facet by facet and local edge index.
index_t create_triangles(index_t nb_triangles)
Creates a contiguous chunk of triangles.
index_t next_corner_around_facet(index_t f, index_t c) const
Gets the successor of a corner around a facet.
auto triangle_points(index_t f) const
Decomposes a facet into triangles.
Base class for mesh sub-element storage.
index_as_iterator begin() const
Used by range-based for.
virtual ~MeshSubElementsStore()
MeshElementStore destructor.
AttributesManager & attributes() const
Gets the attributes manager.
MeshSubElementsStore(Mesh &mesh)
Constructs a new MeshSubElementStore.
index_t create_sub_element()
Creates attributes for a sub-element.
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.
index_t nb() const
Gets the number of (sub-)elements.
void reserve_store(index_t nb_to_reserve)
Reserves space for new elements.
index_as_iterator end() const
Used by range-based for.
void copy(const MeshSubElementsStore &rhs, bool copy_attributes=true)
Copies a MeshSubElementsStore into this one.
void adjust_store()
Makes the size of the store tightly match the number of the elements.
virtual void resize_store(index_t new_size)
Resizes this MeshSubElementsStore.
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.
index_t create_vertex(const double *coords)
Creates a new vertex.
index_t create_vertex(const vecng< DIM, double > &p)
Creates a vertex from a 3d point.
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.
const double * point_ptr(index_t v) const
Gets a point.
const vecng< DIM, double > & point(index_t v) const
Gets a point.
float * single_precision_point_ptr(index_t v)
Gets a (single-precision) point.
auto points()
Gets the 3D points of the mesh as an iterable sequence.
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.
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.
vector< double > & point_coordinates()
Gets the coordinates of all the points as a single vector.
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.
bool single_precision() const
Tests whether vertices are stored in single-precision mode.
const vector< double > & point_coordinates() const
Gets the coordinates of all the points as a single vector.
vecng< DIM, double > & point(index_t v)
Gets a point.
index_t dimension() const
Gets the dimension of the vertices.
index_t create_vertices(index_t nb)
Creates a contiguous chunk of vertices.
void set_single_precision()
Sets single precision mode.
double * point_ptr(index_t v)
Gets a point.
index_t create_vertex()
Creates a new vertex.
void delete_elements(vector< index_t > &to_delete, bool remove_isolated_vertices=true) override
Deletes a set of elements.
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.
bool load(const std::string &filename)
Loads this mesh from a file.
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.
bool save(const std::string &filename) const
Saves this mesh to a file.
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.
A generic index_range bounded by two "non-iterators".
T * data()
Gets modifiable vector data.
Vector with aligned memory allocation.
T * data()
Gets a pointer to the array of elements.
index_t size() const
Gets the number of elements.
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.
CellDescriptor * cell_type_to_cell_descriptor[GEO::MESH_NB_CELL_TYPES]
Maps a cell type to the associated cell descriptor.
Global Vorpaline namespace.
auto transform_range_ref(const RANGE &range, XFORM xform)
Creates a range that applies a user-defined function to each element when accessed.
auto transform_range(const RANGE &range, XFORM xform)
Creates a range that applies a user-defined function to each element when accessed.
geo_index_t index_t
The type for storing and manipulating indices.
geo_coord_index_t coord_index_t
The type for storing coordinate indices, and iterating on the coordinates of a point.
C++-20 like helpers for manipulating ranges of integers.
Lookup tables that describe the combinatorics of each cell type.
index_t nb_vertices_in_facet[6]
index_t facet_vertex[6][4]
index_t edge_adjacent_facet[12][2]
index_t edge_vertex[12][2]