Skip to content

Commit 196ffd6

Browse files
committed
Modified constraint and layout to remove assumptions
1 parent fd883c0 commit 196ffd6

File tree

6 files changed

+112
-58
lines changed

6 files changed

+112
-58
lines changed

src/core/constraint.cpp

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ void vertex_angles_with_jacobian_helper(
143143
std::vector<int> v_rep;
144144
int num_angles;
145145
if (only_free_vertices) {
146-
build_free_vertex_map(cone_metric, v_rep, num_angles);
146+
build_free_vertex_rep(cone_metric, v_rep, num_angles);
147147
} else {
148148
v_rep = cone_metric.v_rep;
149149
num_angles = cone_metric.n_ind_vertices();
@@ -247,19 +247,27 @@ bool constraint_with_jacobian(
247247
return true;
248248
}
249249

250-
void build_free_vertex_map(const Mesh<Scalar>& m, std::vector<int>& v_rep, int& num_free_vertices)
250+
void build_free_vertex_map(const Mesh<Scalar>& m, std::vector<int>& v_map, int& num_free_vertices)
251251
{
252252
// Build map from independent vertices to free vertices
253253
int num_ind_vertices = m.n_ind_vertices();
254254
num_free_vertices = 0;
255-
std::vector<int> v_map(num_ind_vertices, -1);
255+
v_map = std::vector<int>(num_ind_vertices, -1);
256256
for (int v = 0; v < num_ind_vertices; ++v) {
257257
if (!m.fixed_dof[v]) {
258258
v_map[v] = num_free_vertices;
259259
num_free_vertices++;
260260
}
261261
}
262262

263+
}
264+
265+
void build_free_vertex_rep(const Mesh<Scalar>& m, std::vector<int>& v_rep, int& num_free_vertices)
266+
{
267+
// Build vertex map
268+
std::vector<int> v_map;
269+
build_free_vertex_map(m, v_map, num_free_vertices);
270+
263271
// Build map from vertices to free vertices
264272
int num_vertices = m.v_rep.size();
265273
v_rep.resize(num_vertices);

src/core/constraint.hh

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,19 @@ bool constraint_with_jacobian(
8484
bool need_jacobian = true,
8585
bool only_free_vertices = true);
8686

87+
/// Build a map from independent vertices to only vertices marked as free in the mesh
88+
///
89+
/// @param[in] m: mesh
90+
/// @param[out] v_mao: map from independent vertices to free vertex index or -1 for fixed vertices
91+
/// @param[out] num_free_vertices: number of free vertices
92+
void build_free_vertex_map(const Mesh<Scalar>& m, std::vector<int>& v_map, int& num_free_vertices);
8793

8894
/// Build a map from all vertices to only vertices marked as free in the mesh
8995
///
9096
/// @param[in] m: mesh
9197
/// @param[out] v_rep: map from all vertices to free vertex index or -1 for fixed vertices
9298
/// @param[out] num_free_vertices: number of free vertices
93-
void build_free_vertex_map(const Mesh<Scalar>& m, std::vector<int>& v_rep, int& num_free_vertices);
99+
void build_free_vertex_rep(const Mesh<Scalar>& m, std::vector<int>& v_rep, int& num_free_vertices);
94100

95101
/// Compute the maximum cone angle constraint error.
96102
///

src/parameterization/layout.cpp

Lines changed: 20 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -75,21 +75,22 @@ OverlayMesh<Scalar> add_overlay(const Mesh<Scalar>& m, const VectorX& reduced_me
7575
return mo;
7676
}
7777

78-
void make_tufted_overlay(
79-
OverlayMesh<Scalar>& mo,
80-
const Eigen::MatrixXd& V,
81-
const Eigen::MatrixXi& F,
82-
const std::vector<Scalar>& Theta_hat)
78+
void make_tufted_overlay(OverlayMesh<Scalar>& mo)
8379
{
84-
std::vector<int> vtx_reindex, indep_vtx, dep_vtx, v_rep, bnd_loops;
85-
FV_to_double(V, F, V, F, Theta_hat, vtx_reindex, indep_vtx, dep_vtx, v_rep, bnd_loops);
86-
87-
if (bnd_loops.size() != 0) {
88-
int n_v = V.rows();
89-
auto mc = mo.cmesh();
90-
create_tufted_cover(mo._m.type, mo._m.R, indep_vtx, dep_vtx, v_rep, mo._m.out, mo._m.to);
91-
mo._m.v_rep = range(0, n_v);
80+
auto& m = mo._m;
81+
if (m.type[0] == 0) return; // nothing to do for closed mesh
82+
83+
int n_ind_v = m.n_ind_vertices();
84+
int n_he = m.n_halfedges();
85+
86+
// Modify the to and out arrays to identify dependent vertices with their reflection
87+
m.out = std::vector<int>(n_ind_v);
88+
for (int i = 0; i < n_he; ++i)
89+
{
90+
m.out[m.v_rep[m.to[i]]] = i;
91+
m.to[i] = m.v_rep[m.to[i]];
9292
}
93+
m.v_rep = range(0, n_ind_v);
9394
}
9495

9596
bool check_areas(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F)
@@ -889,47 +890,34 @@ std::
889890
std::vector<std::pair<int, int>> // endpoints_o
890891
>
891892
consistent_overlay_mesh_to_VL(
892-
const Eigen::MatrixXi& F,
893-
const std::vector<Scalar>& Theta_hat,
894893
OverlayMesh<Scalar>& mo,
894+
const std::vector<int>& vtx_reindex,
895+
const std::vector<bool>& is_bd,
895896
std::vector<Scalar>& u,
896897
std::vector<std::vector<Scalar>>& V_overlay,
897-
std::vector<int>& vtx_reindex,
898898
std::vector<std::pair<int, int>>& endpoints,
899899
const std::vector<bool>& is_cut_orig,
900900
const std::vector<bool>& is_cut)
901901
{
902+
const auto& m = mo.cmesh();
903+
902904
// get cones and bd
903905
std::vector<int> cones, bd;
904-
std::vector<bool> is_bd = igl::is_border_vertex(F);
905906
for (size_t i = 0; i < is_bd.size(); i++) {
906907
if (is_bd[i]) {
907908
bd.push_back(i);
908909
}
909910
}
910-
for (size_t i = 0; i < Theta_hat.size(); i++) {
911-
if ((!is_bd[i]) && abs(Theta_hat[i] - 2 * M_PI) > 1e-15) {
911+
for (size_t i = 0; i < m.Th_hat.size(); i++) {
912+
if ((!is_bd[i]) && abs(m.Th_hat[i] - 2 * M_PI) > 1e-15) {
912913
cones.push_back(i);
913914
}
914915
}
915916

916917
std::vector<int> f_labels = get_overlay_face_labels(mo);
917918

918-
// reindex cones and bd
919-
std::vector<int> vtx_reindex_rev(vtx_reindex.size());
920-
for (size_t i = 0; i < vtx_reindex.size(); i++) {
921-
vtx_reindex_rev[vtx_reindex[i]] = i;
922-
}
923-
for (size_t i = 0; i < cones.size(); i++) {
924-
cones[i] = vtx_reindex_rev[cones[i]];
925-
}
926-
for (size_t i = 0; i < bd.size(); i++) {
927-
bd[i] = vtx_reindex_rev[bd[i]];
928-
}
929-
930919
spdlog::trace("#bd_vt: {}", bd.size());
931920
spdlog::trace("#cones: {}", cones.size());
932-
spdlog::trace("vtx reindex size: {}", vtx_reindex.size());
933921
spdlog::trace("mc.out size: {}", mo.cmesh().out.size());
934922

935923
// get layout

src/parameterization/layout.hh

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -49,15 +49,7 @@ OverlayMesh<Scalar> add_overlay(const Mesh<Scalar>& m, const VectorX& reduced_me
4949
/// @brief: Make an overlay mesh into a tufted double cover
5050
///
5151
/// @param[in] mo: mesh to make tufted
52-
/// @param[in] V: original vertices used to generate mo
53-
/// @param[in] F: original face array used to generate mo
54-
/// @param[in] Theta_hat: original angles used to generate mo
55-
/// FIXME This should not build the vertex information internally.
56-
void make_tufted_overlay(
57-
OverlayMesh<Scalar>& mo,
58-
const Eigen::MatrixXd& V,
59-
const Eigen::MatrixXi& F,
60-
const std::vector<Scalar>& Theta_hat);
52+
void make_tufted_overlay(OverlayMesh<Scalar>& mo);
6153

6254
/// Given a VF mesh, check that the face areas are nonzero
6355
///
@@ -165,12 +157,11 @@ std::
165157
std::vector<std::pair<int, int>> // endpoints_o
166158
>
167159
consistent_overlay_mesh_to_VL(
168-
const Eigen::MatrixXi& F,
169-
const std::vector<Scalar>& Theta_hat,
170160
OverlayMesh<Scalar>& mo,
161+
const std::vector<int>& vtx_reindex,
162+
const std::vector<bool>& is_bd,
171163
std::vector<Scalar>& u,
172164
std::vector<std::vector<Scalar>>& V_overlay,
173-
std::vector<int>& vtx_reindex,
174165
std::vector<std::pair<int, int>>& endpoints,
175166
const std::vector<bool>& is_cut_orig,
176167
const std::vector<bool>& is_cut);

src/penner_optimization_interface.cpp

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -168,7 +168,6 @@ void write_obj_with_uv(
168168
igl::writeOBJ(filename, V, F, N, FN, uv, F_uv);
169169
}
170170

171-
172171
std::
173172
tuple<
174173
OverlayMesh<Scalar>, // m_o
@@ -195,11 +194,52 @@ std::
195194
Mesh<Scalar> m =
196195
FV_to_double(V, F, V, F, Th_hat, vtx_reindex, indep_vtx, dep_vtx, v_rep, bnd_loops);
197196

197+
return generate_VF_mesh_from_halfedge_metric(V, m, vtx_reindex, initial_cone_metric, reduced_metric_coords, cut_h, do_best_fit_scaling);
198+
}
199+
200+
201+
std::vector<bool> find_boundary_vertices(const Mesh<Scalar>& m)
202+
{
203+
std::vector<bool> is_bd(m.n_ind_vertices(), false);
204+
for (int i = 0; i < m.n_halfedges(); i++) {
205+
if ((m.type[i] == 1) && (m.type[m.opp[i]] == 2))
206+
{
207+
is_bd[m.v_rep[m.to[i]]] = true;
208+
}
209+
}
210+
211+
return is_bd;
212+
}
213+
214+
std::
215+
tuple<
216+
OverlayMesh<Scalar>, // m_o
217+
Eigen::MatrixXd, // V_o
218+
Eigen::MatrixXi, // F_o
219+
Eigen::MatrixXd, // uv_o
220+
Eigen::MatrixXi, // FT_o
221+
std::vector<bool>, // is_cut_h
222+
std::vector<bool>, // is_cut_o
223+
std::vector<int>, // Fn_to_F
224+
std::vector<std::pair<int, int>> // endpoints_o
225+
>
226+
generate_VF_mesh_from_halfedge_metric(
227+
const Eigen::MatrixXd& V,
228+
const Mesh<Scalar>& m,
229+
const std::vector<int>& vtx_reindex,
230+
const DifferentiableConeMetric& initial_cone_metric,
231+
const VectorX& reduced_metric_coords,
232+
std::vector<bool> cut_h,
233+
bool do_best_fit_scaling)
234+
{
198235
// Get metric target coordinates
199236
auto cone_metric = initial_cone_metric.set_metric_coordinates(reduced_metric_coords);
200237
VectorX metric_target = initial_cone_metric.get_metric_coordinates();
201238
VectorX metric_coords = cone_metric->get_metric_coordinates();
202239

240+
// Get boundary vertices
241+
std::vector<bool> is_bd = find_boundary_vertices(m);
242+
203243
// Fit conformal scale factors
204244
VectorX metric_coords_scaled = metric_coords;
205245
VectorX scale_factors;
@@ -241,7 +281,7 @@ std::
241281
reverse_interpolation_mesh,
242282
V_overlay);
243283
OverlayMesh<Scalar> m_o = interpolation_mesh.get_overlay_mesh();
244-
make_tufted_overlay(m_o, V, F, Th_hat);
284+
make_tufted_overlay(m_o);
245285

246286
// Get endpoints
247287
std::vector<std::pair<int, int>> endpoints;
@@ -267,12 +307,11 @@ std::
267307
// auto parametrize_res = overlay_mesh_to_VL<Scalar>(V, F, Th_hat, m_o, u, V_overlay_vec,
268308
// vtx_reindex_mutable, endpoints, -1); FIXME
269309
return consistent_overlay_mesh_to_VL(
270-
F,
271-
Th_hat,
272310
m_o,
311+
vtx_reindex,
312+
is_bd,
273313
u,
274314
V_overlay_vec,
275-
vtx_reindex_mutable,
276315
endpoints,
277316
is_cut,
278317
{});
@@ -298,6 +337,9 @@ std::
298337
Mesh<Scalar> m =
299338
FV_to_double(V, F, V, F, Th_hat, vtx_reindex, indep_vtx, dep_vtx, v_rep, bnd_loops);
300339

340+
// Get boundary vertices
341+
std::vector<bool> is_bd = find_boundary_vertices(m);
342+
301343
// Get layout topology from mesh
302344
std::vector<bool> is_cut = compute_layout_topology(m, cut_h);
303345

@@ -306,7 +348,7 @@ std::
306348

307349
// Create trivial overlay mesh
308350
OverlayMesh<Scalar> m_o(discrete_metric);
309-
make_tufted_overlay(m_o, V, F, Th_hat);
351+
make_tufted_overlay(m_o);
310352

311353
// Convert vertices to transposed vector format
312354
std::vector<std::vector<Scalar>> V_overlay_vec(3);
@@ -323,14 +365,13 @@ std::
323365

324366
// Compute layout
325367
std::vector<Scalar> u_vec(m.n_ind_vertices(), 0.0);
326-
std::vector<int> vtx_reindex_mutable = vtx_reindex;
368+
//std::vector<int> vtx_reindex_mutable = vtx_reindex;
327369
auto layout_res = consistent_overlay_mesh_to_VL(
328-
F,
329-
Th_hat,
330370
m_o,
371+
vtx_reindex,
372+
is_bd,
331373
u_vec,
332374
V_overlay_vec,
333-
vtx_reindex_mutable,
334375
endpoints,
335376
is_cut,
336377
{});

src/penner_optimization_interface.hh

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,26 @@ std::
125125
const VectorX& reduced_metric_coords,
126126
std::vector<bool> is_cut = {},
127127
bool do_best_fit_scaling = false);
128+
std::
129+
tuple<
130+
OverlayMesh<Scalar>, // m_o
131+
Eigen::MatrixXd, // V_o
132+
Eigen::MatrixXi, // F_o
133+
Eigen::MatrixXd, // uv_o
134+
Eigen::MatrixXi, // FT_o
135+
std::vector<bool>, // is_cut_h
136+
std::vector<bool>, // is_cut_o
137+
std::vector<int>, // Fn_to_F
138+
std::vector<std::pair<int, int>> // endpoints_o
139+
>
140+
generate_VF_mesh_from_halfedge_metric(
141+
const Eigen::MatrixXd& V,
142+
const Mesh<Scalar>& m,
143+
const std::vector<int>& vtx_reindex,
144+
const DifferentiableConeMetric& initial_cone_metric,
145+
const VectorX& reduced_metric_coords,
146+
std::vector<bool> cut_h,
147+
bool do_best_fit_scaling);
128148

129149
std::
130150
tuple<

0 commit comments

Comments
 (0)