Skip to content

Commit d5d8c80

Browse files
committed
Added more viewer options:
1 parent 0784abd commit d5d8c80

File tree

6 files changed

+108
-3
lines changed

6 files changed

+108
-3
lines changed

include/holonomy/holonomy/core/viewer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ std::tuple<Eigen::MatrixXd, Eigen::VectorXd> generate_cone_vertices(
2626
const std::vector<int>& vtx_reindex,
2727
const Mesh<Scalar>& m);
2828

29+
std::tuple<Eigen::MatrixXd, Eigen::VectorXd> generate_closed_cone_vertices(
30+
const Eigen::MatrixXd& V,
31+
const std::vector<Scalar>& Th_hat);
32+
2933
std::tuple<Eigen::MatrixXi, Eigen::MatrixXi> generate_mesh_faces(
3034
const Mesh<Scalar>& m,
3135
const std::vector<int>& vtx_reindex);

include/util/util/linear_algebra.h

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,5 +110,15 @@ void compute_submatrix(
110110
*/
111111
Matrix2x2 compute_rotation(Scalar theta);
112112

113+
/**
114+
* @brief Generate equally spaced values in an interval [a, b]
115+
*
116+
* @param a: starting value
117+
* @param b: ending value
118+
* @param num_steps: number of steps to use in the linspace
119+
* @return a vector of equally spaced values between a and b
120+
*/
121+
std::vector<Scalar> generate_linspace(Scalar a, Scalar b, int num_steps);
122+
113123

114124
} // namespace Penner

include/util/util/vf_mesh.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,18 @@ void remove_unreferenced(
5555
Eigen::MatrixXi& FN,
5656
std::vector<int>& new_to_old_map);
5757

58+
/// Given a mesh with a parametrization, generate the 3D seam polylines
59+
///
60+
/// @param[in] V: mesh vertices
61+
/// @param[in] F: mesh faces
62+
/// @param[in] FT: parametrization faces
63+
/// @return seam vertices
64+
/// @return seam edges
65+
std::tuple<Eigen::MatrixXd, Eigen::MatrixXi> generate_seams(
66+
const Eigen::MatrixXd& V,
67+
const Eigen::MatrixXi& F,
68+
const Eigen::MatrixXi& FT);
69+
5870
/// Given a mesh with a parametrization, cut the mesh along the parametrization seams to
5971
/// create a vertex set corresponding to the faces of the uv domain.
6072
///

src/holonomy/core/viewer.cpp

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,32 @@ std::tuple<Eigen::MatrixXd, Eigen::VectorXd> generate_cone_vertices(
325325
return std::make_tuple(cone_positions, cone_values);
326326
}
327327

328+
std::tuple<Eigen::MatrixXd, Eigen::VectorXd> generate_closed_cone_vertices(
329+
const Eigen::MatrixXd& V,
330+
const std::vector<Scalar>& Th_hat)
331+
{
332+
// get cone indices
333+
int num_vertices = V.rows();
334+
std::vector<int> cone_indices;
335+
cone_indices.reserve(num_vertices);
336+
for (int vi = 0; vi < num_vertices; ++vi) {
337+
if (float_equal(Th_hat[vi], 2 * M_PI)) continue;
338+
cone_indices.push_back(vi);
339+
}
340+
341+
// build cone positions and values
342+
int num_cones = cone_indices.size();
343+
Eigen::MatrixXd cone_positions(num_cones, 3);
344+
Eigen::VectorXd cone_values(num_cones);
345+
for (int i = 0; i < num_cones; ++i) {
346+
int vi = cone_indices[i];
347+
cone_positions.row(i) = V.row(vi);
348+
cone_values[i] = (double)(Th_hat[vi]) - (2 * M_PI);
349+
}
350+
351+
return std::make_tuple(cone_positions, cone_values);
352+
}
353+
328354
Eigen::MatrixXd generate_subset_vertices(
329355
const Eigen::MatrixXd& V,
330356
const std::vector<int>& vertex_indices)

src/util/linear_algebra.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,5 +185,22 @@ MatrixX solve_linear_system(const MatrixX& A, const MatrixX&B)
185185
return solver.solve(B);
186186
}
187187

188+
std::vector<Scalar> generate_linspace(Scalar a, Scalar b, int num_steps)
189+
{
190+
std::vector<Scalar> linspace(num_steps + 1);
191+
192+
// iteratively compute linspace
193+
Scalar delta = (b - a) / static_cast<Scalar>(num_steps);
194+
linspace[0] = a;
195+
for (int i = 0; i < num_steps; ++i)
196+
{
197+
linspace[i + 1] = linspace[i] + delta;
198+
}
199+
200+
// clamp last value exactly to b
201+
linspace.back() = b;
202+
203+
return linspace;
204+
}
188205

189206
} // namespace Penner

src/util/vf_mesh.cpp

Lines changed: 39 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434

3535
#include <igl/facet_components.h>
3636
#include <igl/boundary_facets.h>
37+
#include <igl/remove_unreferenced.h>
3738
#include <igl/unique.h>
3839
#include <igl/per_vertex_normals.h>
3940

@@ -52,11 +53,12 @@ void remove_unreferenced(
5253
std::vector<int>& new_to_old_map)
5354
{
5455
int num_faces = F.rows();
56+
int cols = F.cols();
5557

5658
// Iterate over faces to find all referenced vertices in sorted order
5759
std::vector<int> referenced_vertices;
5860
for (int fi = 0; fi < num_faces; ++fi) {
59-
for (int j = 0; j < 3; ++j) {
61+
for (int j = 0; j < cols; ++j) {
6062
int vk = F(fi, j);
6163
referenced_vertices.push_back(vk);
6264
}
@@ -78,9 +80,9 @@ void remove_unreferenced(
7880
}
7981

8082
// Reindex the vertices in the face list
81-
FN.resize(num_faces, 3);
83+
FN.resize(num_faces, cols);
8284
for (int fi = 0; fi < num_faces; ++fi) {
83-
for (int j = 0; j < 3; ++j) {
85+
for (int j = 0; j < cols; ++j) {
8486
int vk = F(fi, j);
8587
int k = old_to_new_map[vk];
8688
FN(fi, j) = k;
@@ -115,6 +117,40 @@ void cut_mesh_along_parametrization_seams(
115117
}
116118
}
117119

120+
std::tuple<Eigen::MatrixXd, Eigen::MatrixXi> generate_seams(
121+
const Eigen::MatrixXd& V,
122+
const Eigen::MatrixXi& F,
123+
const Eigen::MatrixXi& FT)
124+
{
125+
// get boundary edges of the uv map
126+
Eigen::MatrixXi uv_edges;
127+
Eigen::VectorXi J, K;
128+
igl::boundary_facets(FT, uv_edges, J, K);
129+
130+
// get 3D vertices on seam
131+
int num_seam_edges = J.size();
132+
Eigen::MatrixXi edges(num_seam_edges, 2);
133+
for (int i = 0; i < num_seam_edges; ++i)
134+
{
135+
edges(i, 0) = F(J[i], (K[i] + 1)%3);
136+
edges(i, 1) = F(J[i], (K[i] + 2)%3);
137+
}
138+
139+
// reindex to remove redundant
140+
Eigen::MatrixXi seam_edges;
141+
std::vector<int> new_to_old_map;
142+
remove_unreferenced(edges, seam_edges, new_to_old_map);
143+
144+
// get new vertices
145+
int num_seam_vertices = new_to_old_map.size();
146+
Eigen::MatrixXd seam_vertices(num_seam_vertices, 3);
147+
for (int i = 0; i < num_seam_vertices; ++i) {
148+
seam_vertices.row(i) = V.row(new_to_old_map[i]);
149+
}
150+
151+
return std::make_tuple(seam_vertices, seam_edges);
152+
}
153+
118154
std::vector<int> find_boundary_vertices(const Eigen::MatrixXi& F)
119155
{
120156
// Get the boundary edges

0 commit comments

Comments
 (0)