22 const Eigen::MatrixXi &f,
23 const Eigen::MatrixXd &
v,
24 Eigen::SparseMatrix<double> &vertex_to_face_indices)
27 typedef Eigen::Triplet<double> t;
28 std::vector<t> coefficients;
30 for (
int i = 0; i < f.rows(); i++) {
32 int vertex_index1 = f(i, 0);
33 int vertex_index2 = f(i, 1);
34 int vertex_index3 = f(i, 2);
36 double angle1 =
compute_angle(
v.row(vertex_index2) -
v.row(vertex_index1),
37 v.row(vertex_index3) -
v.row(vertex_index1));
38 double angle2 =
compute_angle(
v.row(vertex_index3) -
v.row(vertex_index2),
39 v.row(vertex_index1) -
v.row(vertex_index2));
40 double angle3 =
compute_angle(
v.row(vertex_index1) -
v.row(vertex_index3),
41 v.row(vertex_index2) -
v.row(vertex_index3));
43 coefficients.push_back(t(vertex_index1, 2 * vertex_index2, angle3));
44 coefficients.push_back(t(vertex_index1, 2 * vertex_index3 + 1, angle2));
46 coefficients.push_back(t(vertex_index2, 2 * vertex_index1 + 1, angle3));
47 coefficients.push_back(t(vertex_index2, 2 * vertex_index3, angle1));
49 coefficients.push_back(t(vertex_index3, 2 * vertex_index1, angle2));
50 coefficients.push_back(t(vertex_index3, 2 * vertex_index2 + 1, angle1));
53 vertex_to_face_indices.setFromTriplets(coefficients.begin(), coefficients.end());
57 const Eigen::MatrixXi &f,
58 const Eigen::MatrixXd &
v,
59 Eigen::SparseMatrix<double> &vertex_to_face_indices)
62 typedef Eigen::Triplet<double> t;
63 std::vector<t> coefficients;
65 for (
int i = 0; i < f.rows(); i++) {
67 int vertex_index1 = f(i, 0);
68 int vertex_index2 = f(i, 1);
69 int vertex_index3 = f(i, 2);
71 double angle1 =
compute_angle(
v.row(vertex_index2) -
v.row(vertex_index1),
72 v.row(vertex_index3) -
v.row(vertex_index1));
73 double angle2 =
compute_angle(
v.row(vertex_index3) -
v.row(vertex_index2),
74 v.row(vertex_index1) -
v.row(vertex_index2));
75 double angle3 =
compute_angle(
v.row(vertex_index1) -
v.row(vertex_index3),
76 v.row(vertex_index2) -
v.row(vertex_index3));
78 coefficients.push_back(t(vertex_index1, 2 * vertex_index2, angle1));
79 coefficients.push_back(t(vertex_index1, 2 * vertex_index3 + 1, angle1));
81 coefficients.push_back(t(vertex_index2, 2 * vertex_index1 + 1, angle2));
82 coefficients.push_back(t(vertex_index2, 2 * vertex_index3, angle2));
84 coefficients.push_back(t(vertex_index3, 2 * vertex_index1, angle3));
85 coefficients.push_back(t(vertex_index3, 2 * vertex_index2 + 1, angle3));
88 vertex_to_face_indices.setFromTriplets(coefficients.begin(), coefficients.end());
94 const Eigen::MatrixXd &
v,
95 const Eigen::MatrixXi &
e,
96 const Eigen::VectorXd &el,
97 const Eigen::VectorXi &bnd,
98 const Eigen::MatrixXd &bnd_uv,
102 int verts_num = uv.rows();
103 int edges_num =
e.rows();
105 Eigen::SparseMatrix<double> vertex_to_angles(verts_num, verts_num * 2);
118 int n_unknowns = verts_num - bnd.size();
119 int n_knowns = bnd.size();
121 Eigen::SparseMatrix<double> aint(n_unknowns, n_unknowns);
122 Eigen::SparseMatrix<double> abnd(n_unknowns, n_knowns);
123 Eigen::VectorXd
z(n_knowns);
125 std::vector<Eigen::Triplet<double>> int_triplet_vector;
126 std::vector<Eigen::Triplet<double>> bnd_triplet_vector;
130 double edge_weight, edge_length;
131 Eigen::RowVector2i edge;
133 int first_vertex, second_vertex;
135 for (
int e_idx = 0; e_idx < edges_num; e_idx++) {
137 edge_length = el(e_idx);
138 first_vertex = edge(0);
139 second_vertex = edge(1);
141 if (first_vertex >= n_knowns) {
143 rowindex = first_vertex - n_knowns;
145 double angle1 = vertex_to_angles.coeff(first_vertex, 2 * second_vertex);
146 double angle2 = vertex_to_angles.coeff(first_vertex, 2 * second_vertex + 1);
150 edge_weight = 1 / tan(angle1) + 1 / tan(angle2);
153 edge_weight = tan(angle1 / 2) + tan(angle2 / 2);
154 edge_weight /= edge_length;
161 int_triplet_vector.push_back(Eigen::Triplet<double>(rowindex, rowindex, edge_weight));
163 if (second_vertex >= n_knowns) {
165 columnindex = second_vertex - n_knowns;
167 int_triplet_vector.push_back(Eigen::Triplet<double>(rowindex, columnindex, -edge_weight));
171 columnindex = second_vertex;
172 bnd_triplet_vector.push_back(Eigen::Triplet<double>(rowindex, columnindex, edge_weight));
177 aint.setFromTriplets(int_triplet_vector.begin(), int_triplet_vector.end());
178 aint.makeCompressed();
180 abnd.setFromTriplets(bnd_triplet_vector.begin(), bnd_triplet_vector.end());
181 abnd.makeCompressed();
183 for (
int i = 0; i < n_unknowns; i++) {
184 double factor = aint.coeff(i, i);
185 aint.row(i) /= factor;
186 abnd.row(i) /= factor;
189 Eigen::SparseLU<Eigen::SparseMatrix<double>> solver;
190 solver.compute(aint);
192 for (
int i = 0; i < 2; i++) {
194 for (
int zindex = 0; zindex < n_knowns; zindex++) {
195 z(zindex) = bnd_uv(bnd(zindex), i);
198 Eigen::VectorXd
b = abnd *
z;
201 uvs = solver.solve(
b);
203 Eigen::VectorXd boundary = bnd_uv.col(i);
204 Eigen::VectorXd interior = uvs;
206 uv.col(i) << boundary, interior;
248 double pi = atan(1) * 4;
249 int boundary_vertices_num = vertex_positions.rows();
251 double angle = 2 * pi / boundary_vertices_num;
253 for (
int i = 0; i < boundary_vertices_num; i++) {
256 vertex_positions(i, 0) = (x * 0.5) + 0.5;
257 vertex_positions(i, 1) = (y * 0.5) + 0.5;
262 const Eigen::MatrixXd &uv,
263 std::vector<int> &flip_idx)
266 for (
int i = 0; i < f.rows(); i++) {
268 Eigen::Vector2d v1_n = uv.row(f(i, 0));
269 Eigen::Vector2d v2_n = uv.row(f(i, 1));
270 Eigen::Vector2d v3_n = uv.row(f(i, 2));
272 Eigen::MatrixXd t2_homo(3, 3);
273 t2_homo.col(0) << v1_n(0), v1_n(1), 1;
274 t2_homo.col(1) << v2_n(0), v2_n(1), 1;
275 t2_homo.col(2) << v3_n(0), v3_n(1), 1;
276 double det = t2_homo.determinant();
279 flip_idx.push_back(i);
void tutte(const Eigen::MatrixXi &f, const Eigen::MatrixXd &v, const Eigen::MatrixXi &e, const Eigen::VectorXd &el, const Eigen::VectorXi &bnd, const Eigen::MatrixXd &bnd_uv, Eigen::MatrixXd &uv)
void mvc(const Eigen::MatrixXi &f, const Eigen::MatrixXd &v, const Eigen::MatrixXi &e, const Eigen::VectorXd &el, const Eigen::VectorXi &bnd, const Eigen::MatrixXd &bnd_uv, Eigen::MatrixXd &uv)
void convex_border_parameterization(const Eigen::MatrixXi &f, const Eigen::MatrixXd &v, const Eigen::MatrixXi &e, const Eigen::VectorXd &el, const Eigen::VectorXi &bnd, const Eigen::MatrixXd &bnd_uv, Eigen::MatrixXd &uv, Method method)
void harmonic(const Eigen::MatrixXi &f, const Eigen::MatrixXd &v, const Eigen::MatrixXi &e, const Eigen::VectorXd &el, const Eigen::VectorXi &bnd, const Eigen::MatrixXd &bnd_uv, Eigen::MatrixXd &uv)