PolyFEM
Loading...
Searching...
No Matches
Mesh2D.cpp
Go to the documentation of this file.
2
4
6
7#include <igl/barycentric_coordinates.h>
8
9#include <geogram/basic/file_system.h>
10#include <geogram/mesh/mesh_io.h>
11#include <geogram/mesh/mesh_geometry.h>
12#include <geogram/mesh/mesh_repair.h>
13
14#include <cassert>
15#include <array>
16
17namespace polyfem
18{
19 namespace mesh
20 {
21 void Mesh2D::get_edges(Eigen::MatrixXd &p0, Eigen::MatrixXd &p1) const
22 {
23 p0.resize(n_edges(), 2);
24 p1.resize(p0.rows(), p0.cols());
25
26 for (GEO::index_t e = 0; e < n_edges(); ++e)
27 {
28 const int v0 = edge_vertex(e, 0);
29 const int v1 = edge_vertex(e, 1);
30
31 p0.row(e) = point(v0);
32 p1.row(e) = point(v1);
33 }
34 }
35
36 void Mesh2D::get_edges(Eigen::MatrixXd &p0, Eigen::MatrixXd &p1, const std::vector<bool> &valid_elements) const
37 {
38 int count = 0;
39 for (size_t i = 0; i < valid_elements.size(); ++i)
40 {
41 if (valid_elements[i])
42 {
43 count += n_face_vertices(i);
44 }
45 }
46
47 p0.resize(count, 2);
48 p1.resize(count, 2);
49
50 count = 0;
51
52 for (size_t i = 0; i < valid_elements.size(); ++i)
53 {
54 if (!valid_elements[i])
55 continue;
56
57 auto index = get_index_from_face(i);
58 for (int j = 0; j < n_face_vertices(i); ++j)
59 {
60 p0.row(count) = point(index.vertex);
61 p1.row(count) = point(switch_vertex(index).vertex);
62
63 index = next_around_face(index);
64 ++count;
65 }
66 }
67 }
68
69 RowVectorNd Mesh2D::face_barycenter(const int face_index) const
70 {
71 RowVectorNd bary(2);
72 bary.setZero();
73
74 const int n_vertices = n_face_vertices(face_index);
75 Navigation::Index index = get_index_from_face(face_index);
76
77 for (int lv = 0; lv < n_vertices; ++lv)
78 {
79 bary += point(index.vertex);
80 index = next_around_face(index);
81 }
82 return bary / n_vertices;
83 }
84
85 void Mesh2D::barycentric_coords(const RowVectorNd &p, const int el_id, Eigen::MatrixXd &coords) const
86 {
87 assert(is_simplex(el_id));
88
89 auto index = get_index_from_face(el_id);
90 const auto A = point(index.vertex);
91
92 index = next_around_face(index);
93 const auto B = point(index.vertex);
94
95 index = next_around_face(index);
96 const auto C = point(index.vertex);
97
98 igl::barycentric_coordinates(p, A, B, C, coords);
99 }
100
101 void Mesh2D::compute_face_jacobian(const int el_id, const Eigen::MatrixXd &reference_map, Eigen::MatrixXd &jacobian) const
102 {
103 assert(is_simplex(el_id));
104
105 auto index = get_index_from_face(el_id);
106 const auto A = point(index.vertex);
107 index = next_around_face(index);
108 const auto B = point(index.vertex);
109 index = next_around_face(index);
110 const auto C = point(index.vertex);
111
112 Eigen::MatrixXd coords(3, 3);
113 coords << A, 1, B, 1, C, 1;
114 coords.transposeInPlace();
115
116 jacobian = coords * reference_map;
117
118 assert(jacobian.determinant() > 0);
119 }
120
121 void Mesh2D::elements_boxes(std::vector<std::array<Eigen::Vector3d, 2>> &boxes) const
122 {
123 boxes.resize(n_elements());
124
125 for (int i = 0; i < n_elements(); ++i)
126 {
127 auto &box = boxes[i];
128 box[0] << std::numeric_limits<double>::max(), std::numeric_limits<double>::max(), 0;
129 box[1] << std::numeric_limits<double>::min(), std::numeric_limits<double>::min(), 0;
130
131 auto index = get_index_from_face(i);
132
133 for (int j = 0; j < n_face_vertices(i); ++j)
134 {
135 for (int d = 0; d < 2; ++d)
136 {
137 box[0][d] = std::min(box[0][d], point(index.vertex)[d]);
138 box[1][d] = std::max(box[1][d], point(index.vertex)[d]);
139 }
140 index = next_around_face(index);
141 }
142 }
143 }
144 } // namespace mesh
145} // namespace polyfem
void elements_boxes(std::vector< std::array< Eigen::Vector3d, 2 > > &boxes) const override
constructs a box around every element (3d cell, 2d face)
Definition Mesh2D.cpp:121
RowVectorNd face_barycenter(const int index) const override
face barycenter
Definition Mesh2D.cpp:69
Navigation::Index next_around_face(Navigation::Index idx) const
Definition Mesh2D.hpp:61
void barycentric_coords(const RowVectorNd &p, const int el_id, Eigen::MatrixXd &coord) const override
constructs barycentric coodiantes for a point p.
Definition Mesh2D.cpp:85
void get_edges(Eigen::MatrixXd &p0, Eigen::MatrixXd &p1) const override
Get all the edges.
Definition Mesh2D.cpp:21
virtual Navigation::Index switch_vertex(Navigation::Index idx) const =0
virtual Navigation::Index get_index_from_face(int f, int lv=0) const =0
void compute_face_jacobian(const int el_id, const Eigen::MatrixXd &reference_map, Eigen::MatrixXd &jacobian) const
Definition Mesh2D.cpp:101
int n_elements() const
utitlity to return the number of elements, cells or faces in 3d and 2d
Definition Mesh.hpp:158
virtual int n_vertices() const =0
number of vertices
virtual RowVectorNd point(const int global_index) const =0
point coordinates
bool is_simplex(const int el_id) const
checks if element is simples compatible
Definition Mesh.cpp:418
virtual int edge_vertex(const int e_id, const int lv_id) const =0
id of the edge vertex
virtual int n_edges() const =0
number of edges
virtual int n_face_vertices(const int f_id) const =0
number of vertices of a face
Eigen::Matrix< double, 1, Eigen::Dynamic, Eigen::RowMajor, 1, 3 > RowVectorNd
Definition Types.hpp:11