14#include <lagrange/ActingMeshGeometry.h>
15#include <lagrange/Attributes.h>
16#include <lagrange/Components.h>
17#include <lagrange/Connectivity.h>
18#include <lagrange/Edge.h>
19#include <lagrange/GenuineMeshGeometry.h>
20#include <lagrange/MeshGeometry.h>
21#include <lagrange/MeshNavigation.h>
22#include <lagrange/MeshTopology.h>
23#include <lagrange/common.h>
24#include <lagrange/corner_to_edge_mapping.h>
25#include <lagrange/experimental/AttributeManager.h>
26#include <lagrange/experimental/IndexedAttributeManager.h>
27#include <lagrange/utils/assert.h>
28#include <lagrange/utils/safe_cast.h>
29#include <lagrange/utils/invalid.h>
46template <
typename _VertexArray,
typename _FacetArray>
50 using VertexArray = _VertexArray;
51 using FacetArray = _FacetArray;
53 Eigen::Matrix<typename VertexArray::Scalar, 1, VertexArray::ColsAtCompileTime>;
56 using Scalar =
typename VertexArray::Scalar;
57 using Index =
typename FacetArray::Scalar;
59 using AttributeArray = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, Eigen::RowMajor>;
60 using IndexArray = FacetArray;
64 using AdjacencyList =
typename Connectivity<Geometry>::AdjacencyList;
65 using IndexList =
typename Connectivity<Geometry>::IndexList;
69 using UVArray = AttributeArray;
70 using UVIndices = IndexArray;
71 using UVType = Eigen::Matrix<Scalar, 1, 2>;
82 m_connectivity = std::make_unique<Connectivity<Geometry>>();
83 m_components = std::make_unique<Components<Geometry>>();
84 m_topology = std::make_unique<MeshTopology<MeshType>>();
87 Mesh(std::shared_ptr<Geometry> geom)
91 m_connectivity = std::make_unique<Connectivity<Geometry>>();
92 m_components = std::make_unique<Components<Geometry>>();
93 m_topology = std::make_unique<MeshTopology<MeshType>>();
96 void operator=(
const Mesh& other) =
delete;
97 virtual ~Mesh() =
default;
100 void initialize(
const VertexArray& vertices,
const FacetArray& facets)
103 std::make_shared<GenuineMeshGeometry<VertexArray, FacetArray>>(vertices, facets);
107 bool is_initialized()
const
109 return m_geometry && m_vertex_attributes && m_facet_attributes && m_corner_attributes &&
110 m_edge_attributes && m_indexed_attributes;
113 Index get_dim()
const
116 return m_geometry->get_dim();
118 Index get_num_vertices()
const
121 return m_geometry->get_num_vertices();
123 Index get_num_facets()
const
126 return m_geometry->get_num_facets();
128 Index get_vertex_per_facet()
const
131 return m_geometry->get_vertex_per_facet();
134 const VertexArray& get_vertices()
const
137 return m_geometry->get_vertices();
139 const FacetArray& get_facets()
const
142 return m_geometry->get_facets();
145 VertexArray& ref_vertices()
148 return m_geometry->get_vertices_ref();
150 FacetArray& ref_facets()
153 return m_geometry->get_facets_ref();
156 std::vector<std::string> get_vertex_attribute_names()
const
159 return m_vertex_attributes->get_names();
162 std::vector<std::string> get_facet_attribute_names()
const
165 return m_facet_attributes->get_names();
168 std::vector<std::string> get_corner_attribute_names()
const
171 return m_corner_attributes->get_names();
174 std::vector<std::string> get_edge_attribute_names()
const
177 return m_edge_attributes->get_names();
180 std::vector<std::string> get_indexed_attribute_names()
const
183 return m_indexed_attributes->get_names();
186 bool has_vertex_attribute(
const std::string& name)
const
189 return m_vertex_attributes->has(name);
192 bool has_facet_attribute(
const std::string& name)
const
195 return m_facet_attributes->has(name);
198 bool has_corner_attribute(
const std::string& name)
const
201 return m_corner_attributes->has(name);
204 bool has_edge_attribute(
const std::string& name)
const
207 return m_edge_attributes->has(name);
210 bool has_indexed_attribute(
const std::string& name)
const
213 return m_indexed_attributes->has(name);
216 void add_vertex_attribute(
const std::string& name)
const
219 m_vertex_attributes->add(name);
222 void add_facet_attribute(
const std::string& name)
const
225 m_facet_attributes->add(name);
228 void add_corner_attribute(
const std::string& name)
const
231 m_corner_attributes->add(name);
234 void add_edge_attribute(
const std::string& name)
const
237 m_edge_attributes->add(name);
240 void add_indexed_attribute(
const std::string& name)
const
243 m_indexed_attributes->add(name);
246 const AttributeArray& get_vertex_attribute(
const std::string& name)
const
249 const auto* attr = m_vertex_attributes->get(name);
250 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
251 return attr->get()->template get<AttributeArray>();
254 decltype(
auto) get_vertex_attribute_array(
const std::string& name)
const
257 const auto* attr = m_vertex_attributes->get(name);
258 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
262 decltype(
auto) get_vertex_attribute_array(
const std::string& name)
265 auto* attr = m_vertex_attributes->get(name);
266 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
271 const AttributeArray& get_facet_attribute(
const std::string& name)
const
274 const auto* attr = m_facet_attributes->get(name);
275 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
276 return attr->get()->template get<AttributeArray>();
279 decltype(
auto) get_facet_attribute_array(
const std::string& name)
const
282 const auto* attr = m_facet_attributes->get(name);
283 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
287 decltype(
auto) get_facet_attribute_array(
const std::string& name)
290 auto* attr = m_facet_attributes->get(name);
291 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
295 const AttributeArray& get_corner_attribute(
const std::string& name)
const
298 const auto* attr = m_corner_attributes->get(name);
299 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
300 return attr->get()->template get<AttributeArray>();
303 decltype(
auto) get_corner_attribute_array(
const std::string& name)
const
306 const auto* attr = m_corner_attributes->get(name);
307 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
311 decltype(
auto) get_corner_attribute_array(
const std::string& name)
314 auto* attr = m_corner_attributes->get(name);
315 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
319 const AttributeArray& get_edge_attribute(
const std::string& name)
const
322 const auto* attr = m_edge_attributes->get(name);
324 return attr->get()->template get<AttributeArray>();
327 decltype(
auto) get_edge_attribute_array(
const std::string& name)
const
330 auto* attr = m_edge_attributes->get(name);
331 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
335 decltype(
auto) get_edge_attribute_array(
const std::string& name)
338 auto* attr = m_edge_attributes->get(name);
339 la_runtime_assert(attr !=
nullptr,
"Attribute " + name +
" is not initialized.");
343 auto get_indexed_attribute(
const std::string& name)
const
346 const auto data = m_indexed_attributes->get(name);
348 return std::forward_as_tuple(
349 data->template get_values<AttributeArray>(),
350 data->template get_indices<IndexArray>());
353 auto get_indexed_attribute_array(
const std::string& name)
const
356 const auto data = m_indexed_attributes->get(name);
358 return std::make_tuple(data->get_values(), data->get_indices());
361 auto get_indexed_attribute_array(
const std::string& name)
364 const auto data = m_indexed_attributes->get(name);
366 return std::make_tuple(data->get_values(), data->get_indices());
369 void set_vertex_attribute(
const std::string& name,
const AttributeArray& attr)
372 m_vertex_attributes->set(name, attr);
375 void set_facet_attribute(
const std::string& name,
const AttributeArray& attr)
378 m_facet_attributes->set(name, attr);
381 void set_corner_attribute(
const std::string& name,
const AttributeArray& attr)
384 m_corner_attributes->set(name, attr);
387 void set_edge_attribute(
const std::string& name,
const AttributeArray& attr)
390 m_edge_attributes->set(name, attr);
393 template <
typename Derived>
394 void set_vertex_attribute_array(
const std::string& name, Derived&& attr)
397 m_vertex_attributes->set(name, std::forward<Derived>(attr));
400 template <
typename Derived>
401 void set_facet_attribute_array(
const std::string& name, Derived&& attr)
404 m_facet_attributes->set(name, std::forward<Derived>(attr));
407 template <
typename Derived>
408 void set_corner_attribute_array(
const std::string& name, Derived&& attr)
411 m_corner_attributes->set(name, std::forward<Derived>(attr));
414 template <
typename Derived>
415 void set_edge_attribute_array(
const std::string& name, Derived&& attr)
418 m_edge_attributes->set(name, std::forward<Derived>(attr));
421 void set_indexed_attribute(
422 const std::string& name,
423 const AttributeArray& values,
424 const IndexArray& indices)
427 auto attr = m_indexed_attributes->get(name);
428 attr->set_values(values);
429 attr->set_indices(indices);
432 void remove_vertex_attribute(
const std::string& name)
435 m_vertex_attributes->remove(name);
438 void remove_facet_attribute(
const std::string& name)
441 m_facet_attributes->remove(name);
444 void remove_corner_attribute(
const std::string& name)
447 m_corner_attributes->remove(name);
450 void remove_edge_attribute(
const std::string& name)
453 m_edge_attributes->remove(name);
456 void remove_indexed_attribute(
const std::string& name)
459 m_indexed_attributes->remove(name);
471 template <
typename Derived>
472 void import_vertices(Eigen::PlainObjectBase<Derived>& vertices)
475 m_geometry->import_vertices(vertices);
478 template <
typename Derived>
479 void import_facets(Eigen::PlainObjectBase<Derived>& facets)
482 m_geometry->import_facets(facets);
485 template <
typename AttributeDerived>
486 void import_vertex_attribute(
const std::string& name, AttributeDerived&& attr)
const
489 m_vertex_attributes->import_data(name, std::forward<AttributeDerived>(attr));
492 template <
typename AttributeDerived>
493 void import_facet_attribute(
const std::string& name, AttributeDerived&& attr)
const
496 m_facet_attributes->import_data(name, std::forward<AttributeDerived>(attr));
499 template <
typename AttributeDerived>
500 void import_corner_attribute(
const std::string& name, AttributeDerived&& attr)
const
503 m_corner_attributes->import_data(name, std::forward<AttributeDerived>(attr));
506 template <
typename AttributeDerived>
507 void import_edge_attribute(
const std::string& name, AttributeDerived&& attr)
const
510 m_edge_attributes->import_data(name, std::forward<AttributeDerived>(attr));
513 template <
typename ValueDerived,
typename IndexDerived>
515 import_indexed_attribute(
const std::string& name, ValueDerived&& values, IndexDerived&& indices)
518 m_indexed_attributes->import_data(
520 std::forward<ValueDerived>(values),
521 std::forward<IndexDerived>(indices));
524 template <
typename Derived>
525 void export_vertices(Eigen::PlainObjectBase<Derived>& vertices)
528 m_geometry->export_vertices(vertices);
531 template <
typename Derived>
532 void export_facets(Eigen::PlainObjectBase<Derived>& facets)
535 m_geometry->export_facets(facets);
538 template <
typename Derived>
539 void export_vertex_attribute(
const std::string& name, Eigen::PlainObjectBase<Derived>& attr)
542 m_vertex_attributes->export_data(name, attr);
545 template <
typename Derived>
546 void export_facet_attribute(
const std::string& name, Eigen::PlainObjectBase<Derived>& attr)
549 m_facet_attributes->export_data(name, attr);
552 template <
typename Derived>
553 void export_corner_attribute(
const std::string& name, Eigen::PlainObjectBase<Derived>& attr)
556 m_corner_attributes->export_data(name, attr);
559 template <
typename Derived>
560 void export_edge_attribute(
const std::string& name, Eigen::PlainObjectBase<Derived>& attr)
563 m_edge_attributes->export_data(name, attr);
566 template <
typename ValueDerived,
typename IndexDerived>
567 void export_indexed_attribute(
568 const std::string& name,
569 Eigen::PlainObjectBase<ValueDerived>& values,
570 Eigen::PlainObjectBase<IndexDerived>& indices)
572 m_indexed_attributes->export_data(name, values, indices);
580 void initialize_connectivity()
583 m_connectivity->initialize(*m_geometry);
586 bool is_connectivity_initialized()
const
588 return (m_connectivity && m_connectivity->is_initialized());
591 const AdjacencyList& get_vertex_vertex_adjacency()
const
594 return m_connectivity->get_vertex_vertex_adjacency();
597 const AdjacencyList& get_vertex_facet_adjacency()
const
600 return m_connectivity->get_vertex_facet_adjacency();
603 const AdjacencyList& get_facet_facet_adjacency()
const
606 return m_connectivity->get_facet_facet_adjacency();
609 const IndexList& get_vertices_adjacent_to_vertex(Index vi)
const
612 return m_connectivity->get_vertices_adjacent_to_vertex(vi);
615 const IndexList& get_facets_adjacent_to_vertex(Index vi)
const
618 return m_connectivity->get_facets_adjacent_to_vertex(vi);
621 const IndexList& get_facets_adjacent_to_facet(Index fi)
const
624 return m_connectivity->get_facets_adjacent_to_facet(fi);
635 if (m_navigation)
return;
636 m_navigation = std::make_unique<MeshNavigation<MeshType>>(std::ref(*
this));
653 return m_navigation->get_num_edges();
667 return m_navigation->get_edge(f, lv);
680 return m_navigation->get_edge_from_corner(c);
697 Index edge_id = invalid<Index>();
699 const Index vertex_per_facet = get_vertex_per_facet();
701 const Index fid = c / vertex_per_facet;
702 const Index lv = c % vertex_per_facet;
703 if (get_facets()(fid, (lv + 1) % vertex_per_facet) == v1) {
707 if (edge_id != invalid<Index>())
return edge_id;
714 const Index fid = c / vertex_per_facet;
715 const Index lv = c % vertex_per_facet;
716 if (get_facets()(fid, (lv + 1) % vertex_per_facet) == v0) {
733 return m_navigation->get_edge_vertices(get_facets(), e);
748 return m_navigation->get_vertex_opposite_edge(get_facets(), e);
760 return m_navigation->get_num_facets_around_vertex(v);
772 return m_navigation->get_num_facets_around_edge(e);
785 return m_navigation->get_one_facet_around_edge(e);
798 return m_navigation->get_one_corner_around_edge(e);
811 return m_navigation->get_one_corner_around_vertex(v);
824 return m_navigation->is_boundary_edge(e);
837 return m_navigation->is_boundary_vertex(v);
850 template <
typename Func>
854 m_navigation->foreach_facets_around_vertex(v, func);
865 template <
typename Func>
869 m_navigation->foreach_facets_around_edge(e, func);
880 template <
typename Func>
884 m_navigation->foreach_corners_around_vertex(v, func);
895 template <
typename Func>
899 m_navigation->foreach_corners_around_edge(e, func);
907 void initialize_topology()
910 m_topology->initialize(*
this);
913 bool is_topology_initialized()
const {
return m_topology->is_initialized(); }
915 bool is_edge_manifold()
const
917 la_runtime_assert(m_topology->is_initialized(),
"Mesh topology not initialized");
918 return m_topology->is_edge_manifold();
921 bool is_vertex_manifold()
const
923 la_runtime_assert(m_topology->is_initialized(),
"Mesh topology not initialized");
924 return m_topology->is_vertex_manifold();
927 const MeshTopology<MeshType>& get_topology()
const {
return *m_topology; }
933 void initialize_components()
937 if (!m_connectivity->is_initialized()) {
938 initialize_connectivity();
940 m_components->initialize(*m_geometry, m_connectivity.get());
943 bool is_components_initialized()
const
945 return (m_components && (get_num_facets() == 0 || m_components->get_num_components() > 0));
948 Index get_num_components()
const
951 return m_components->get_num_components();
954 const std::vector<IndexList>& get_components()
const
957 return m_components->get_components();
960 const IndexList& get_per_facet_component_ids()
const
963 return m_components->get_per_facet_component_ids();
971 bool is_uv_initialized()
const {
return m_indexed_attributes->has(
"uv"); }
973 void initialize_uv(
const UVArray& uv,
const UVIndices& uv_indices)
975 if (!m_indexed_attributes->has(
"uv")) {
976 m_indexed_attributes->add(
"uv");
978 auto uv_attr = m_indexed_attributes->get(
"uv");
980 uv_attr->set_values(uv);
981 uv_attr->set_indices(uv_indices);
984 void import_uv(UVArray&& uv, UVIndices&& uv_indices)
986 if (!m_indexed_attributes->has(
"uv")) {
987 m_indexed_attributes->add(
"uv");
989 this->import_indexed_attribute(
"uv", uv, uv_indices);
992 decltype(
auto) get_uv()
const
995 return m_indexed_attributes->get_values<UVArray>(
"uv");
998 decltype(
auto) get_uv_indices()
const
1001 return m_indexed_attributes->get_indices<UVIndices>(
"uv");
1004 decltype(
auto) get_uv_mesh()
const
1006 const auto attr = m_indexed_attributes->get(
"uv");
1007 auto geometry = std::make_unique<GenuineMeshGeometry<UVArray, UVIndices>>(
1008 attr->get_values()->template get<UVArray>(),
1009 attr->get_indices()->template get<UVIndices>());
1010 return std::make_unique<Mesh<UVArray, UVIndices>>(std::move(geometry));
1013 void clear_uv()
const { m_indexed_attributes->remove(
"uv"); }
1020 template <
typename Archive>
1021 void serialize_impl(Archive& ar)
1024 const std::array<int32_t, 3> current_version = {{0, 1, 0}};
1025 std::array<int32_t, 3> version = current_version;
1026 if (ar.is_input()) {
1037 DEPRECATED_EDGE_ATTR = 7,
1039 ar.object([&](
auto& ar) {
1040 ar(
"version", VERSION) & version;
1041 ar(
"geometry", GEOMETRY) & m_geometry;
1042 ar(
"vertex_attributes", VERTEX_ATTR) & m_vertex_attributes;
1043 ar(
"facet_attributes", FACET_ATTR) & m_facet_attributes;
1044 ar(
"corner_attributes", CORNER_ATTR) & m_corner_attributes;
1045 ar(
"edge_attributes", EDGE_ATTR) & m_edge_attributes;
1046 ar(
"indexed_attributes", INDEXED_ATTR) & m_indexed_attributes;
1049 LA_IGNORE_SHADOW_WARNING_END
1052 if (ar.is_input()) {
1053 if (m_edge_attributes->get_size() > 0) {
1061 if (ar.is_input()) {
1062 const auto names = m_indexed_attributes->get_names();
1063 for (
const auto& name : names) {
1064 AttributeArray values = m_indexed_attributes->view_values<AttributeArray>(name);
1065 IndexArray indices = m_indexed_attributes->view_indices<IndexArray>(name);
1066 m_indexed_attributes->remove(name);
1067 m_indexed_attributes->add(name, std::move(values), std::move(indices));
1073 void init_attributes()
1075 m_vertex_attributes = std::make_unique<experimental::AttributeManager>();
1076 m_facet_attributes = std::make_unique<experimental::AttributeManager>();
1077 m_corner_attributes = std::make_unique<experimental::AttributeManager>();
1078 m_edge_attributes = std::make_unique<experimental::AttributeManager>();
1079 m_indexed_attributes = std::make_unique<experimental::IndexedAttributeManager>();
1083 std::shared_ptr<Geometry> m_geometry;
1084 std::unique_ptr<MeshTopology<MeshType>> m_topology;
1085 std::unique_ptr<MeshNavigation<MeshType>> m_navigation;
1087 std::unique_ptr<Connectivity<Geometry>> m_connectivity;
1088 std::unique_ptr<Components<Geometry>> m_components;
1089 std::unique_ptr<experimental::AttributeManager> m_vertex_attributes;
1090 std::unique_ptr<experimental::AttributeManager> m_facet_attributes;
1091 std::unique_ptr<experimental::AttributeManager> m_corner_attributes;
1092 std::unique_ptr<experimental::AttributeManager> m_edge_attributes;
1093 std::unique_ptr<experimental::IndexedAttributeManager> m_indexed_attributes;
1096template <
typename _VertexArray,
typename _FacetArray,
typename Archive>
1097void serialize(Mesh<_VertexArray, _FacetArray>& mesh, Archive& ar)
1099 mesh.serialize_impl(ar);
1102extern template class Mesh<Vertices3D, Triangles>;
1103extern template class Mesh<Vertices2D, Triangles>;
1104extern template class Mesh<Vertices3Df, Triangles>;
1105extern template class Mesh<Vertices2Df, Triangles>;
1106extern template class Mesh<Vertices3D, Quads>;
1107extern template class Mesh<Vertices2D, Quads>;
1108extern template class Mesh<Vertices3Df, Quads>;
1109extern template class Mesh<Vertices2Df, Quads>;
Definition: MeshGeometry.h:25
Index find_edge_from_vertices(Index v0, Index v1) const
Retrieve the edge id from end vertices (v0, v1).
Definition: Mesh.h:694
bool is_boundary_edge(Index e) const
Determines whether the specified edge e is a boundary edge.
Definition: Mesh.h:821
bool is_boundary_vertex(Index v) const
Determines whether the specified vertex v is a boundary vertex.
Definition: Mesh.h:834
Index get_vertex_opposite_edge(Index e) const
Returns a vertex id opposite the edge.
Definition: Mesh.h:745
Index get_num_facets_around_vertex(Index v) const
Count the number of facets incident to a given vertex.
Definition: Mesh.h:757
Index get_one_corner_around_edge(Index e) const
Get the index of one corner around a given edge.
Definition: Mesh.h:795
Mesh()
The default constructor only build a frame of the data structure with null geometry and attributes.
Definition: Mesh.h:80
bool is_edge_data_initialized() const
Edge data accessors (const)
Definition: Mesh.h:643
Index get_edge(Index f, Index lv) const
Gets the edge index corresponding to (f, lv) – (f, lv+1).
Definition: Mesh.h:664
std::array< Index, 2 > get_edge_vertices(Index e) const
Retrieve edge endpoints.
Definition: Mesh.h:730
void initialize_edge_data()
Edge data initialization.
Definition: Mesh.h:633
Index get_num_facets_around_edge(Index e) const
Count the number of facets incident to a given edge.
Definition: Mesh.h:769
void foreach_facets_around_edge(Index e, Func func) const
Applies a function to each facet around a prescribed edge.
Definition: Mesh.h:866
void foreach_corners_around_edge(Index e, Func func) const
Applies a function to each corner around a prescribed edge.
Definition: Mesh.h:896
Index get_one_facet_around_edge(Index e) const
Get the index of one facet around a given edge.
Definition: Mesh.h:782
Index get_one_corner_around_vertex(Index v) const
Get the index of one corner around a given vertex.
Definition: Mesh.h:808
Index get_num_edges() const
Gets the number of edges.
Definition: Mesh.h:650
void foreach_facets_around_vertex(Index v, Func func) const
Applies a function to each facet around a prescribed vertex.
Definition: Mesh.h:851
void foreach_corners_around_vertex(Index v, Func func) const
Applies a function to each corner around a prescribed vertex.
Definition: Mesh.h:881
Index get_edge_from_corner(Index c) const
Gets the edge index corresponding to a corner index.
Definition: Mesh.h:677
void clear_edge_data()
Clear edge data.
Definition: Mesh.h:640
#define la_runtime_assert(...)
Runtime assertion check.
Definition: assert.h:169
#define LA_IGNORE_SHADOW_WARNING_BEGIN
Ignore shadow warnings.
Definition: warning.h:68
Main namespace for Lagrange.
Definition: AABBIGL.h:30