Skip to content

Commit 0784abd

Browse files
committed
Added cones and field to output of scripts
1 parent 80c46a5 commit 0784abd

File tree

7 files changed

+44
-32
lines changed

7 files changed

+44
-32
lines changed

include/holonomy/holonomy/core/intrinsic_field.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ class IntrinsicNRosyField
1515
const std::vector<int>& vtx_reindex,
1616
const Eigen::MatrixXd& V);
1717

18-
Scalar min_angle = 1e-3;
18+
Scalar min_angle = 0.;
1919

2020
private:
2121
// Local frames
@@ -59,4 +59,4 @@ class IntrinsicNRosyField
5959
};
6060

6161
} // namespace Holonomy
62-
} // namespace Penner
62+
} // namespace Penner

scripts/holonomy_overlay.py

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,29 @@ def similarity_overlay_one(args, fname):
2525
output_dir = script_util.get_mesh_output_directory(args['output_dir'], m)
2626
os.makedirs(output_dir, exist_ok=True)
2727

28+
# Skip meshes that are already processed
29+
try:
30+
uv_mesh_path = os.path.join(output_dir, name + '_refined_with_uv.obj')
31+
V, F = igl.read_triangle_mesh(uv_mesh_path)
32+
if (len(V) > 0):
33+
print("Skipping processed mesh")
34+
return
35+
except:
36+
pass
37+
2838
# Get logger
2939
log_path = os.path.join(output_dir, name+'_convert_to_vf.log')
3040
logger = script_util.get_logger(log_path)
3141
logger.info("Converting {} to vf".format(name))
3242

3343
try:
3444
V, F = igl.read_triangle_mesh(os.path.join(args['input_dir'], fname))
45+
Th_hat = np.loadtxt(os.path.join(output_dir, m + '_Th_hat'), dtype=float)
46+
rotation_form = np.loadtxt(os.path.join(output_dir, m + '_kappa_hat'), dtype=float)
3547
except:
3648
logger.info("Could not open mesh data at {}", args['input_dir'])
3749
return
3850

39-
if args['fit_field']:
40-
field_params = holonomy.FieldParameters()
41-
field_params.min_angle = np.pi
42-
rotation_form, Th_hat = holonomy.generate_intrinsic_rotation_form(V, F, field_params)
43-
else:
44-
try:
45-
Th_hat = np.loadtxt(os.path.join(args['input_dir'], name + "_Th_hat"), dtype=float)
46-
rotation_form = np.loadtxt(os.path.join(args['input_dir'], name + "_kappa_hat"), dtype=float)
47-
except:
48-
logger.info("Could not open rotation form")
49-
return
50-
5151
# Get final optimized lambdas
5252
try:
5353
metric_coords_path = os.path.join(output_dir, name + "_metric_coords")
@@ -95,11 +95,6 @@ def similarity_overlay_one(args, fname):
9595
refinement_mesh = opt.RefinementMesh(V_o, F_o, uv_o, FT_o, fn_to_f_o, endpoints_o)
9696
V_r, F_r, uv_r, FT_r, fn_to_f_r, endpoints_r = refinement_mesh.get_VF_mesh()
9797

98-
# Write combined refined mesh with uv
99-
uv_mesh_path = os.path.join(output_dir, name + '_refined_with_uv.obj')
100-
logger.info("Saving refined uv mesh at {}".format(uv_mesh_path))
101-
opt.write_obj_with_uv(uv_mesh_path, V_r, F_r, uv_r, FT_r)
102-
10398
# Save cut information
10499
simp_path = os.path.join(output_dir, name + '_is_cut_h')
105100
logger.info("Saving cut information at {}".format(simp_path))
@@ -137,6 +132,11 @@ def similarity_overlay_one(args, fname):
137132
logger.info("Saving endpoints at {}".format(endpoints_path))
138133
np.savetxt(endpoints_path, endpoints_o, fmt='%i')
139134

135+
# Write combined refined mesh with uv
136+
uv_mesh_path = os.path.join(output_dir, name + '_refined_with_uv.obj')
137+
logger.info("Saving refined uv mesh at {}".format(uv_mesh_path))
138+
opt.write_obj_with_uv(uv_mesh_path, V_r, F_r, uv_r, FT_r)
139+
140140
def similarity_overlay_many(args):
141141
script_util.run_many(similarity_overlay_one, args)
142142

scripts/optimize_angles.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ def constrain_similarity_one(args, fname):
3535
except:
3636
pass
3737

38+
# get triangle mesh
3839
try:
3940
V, F = igl.read_triangle_mesh(os.path.join(args['input_dir'], fname))
4041
if (len(V) < 4):
@@ -44,7 +45,9 @@ def constrain_similarity_one(args, fname):
4445
logger.info("Could not open mesh data")
4546
return
4647

48+
# get precomputed form, or generate on the fly
4749
if args['fit_field']:
50+
logger.info("Fitting cross field")
4851
field_params = holonomy.FieldParameters()
4952
field_params.min_angle = np.pi
5053
rotation_form, Th_hat = holonomy.generate_intrinsic_rotation_form(V, F, field_params)
@@ -56,6 +59,12 @@ def constrain_similarity_one(args, fname):
5659
logger.info("Could not open rotation form")
5760
return
5861

62+
# save form to output file
63+
output_path = os.path.join(output_dir, name + '_Th_hat')
64+
np.savetxt(output_path, Th_hat)
65+
output_path = os.path.join(output_dir, name + '_kappa_hat')
66+
np.savetxt(output_path, rotation_form)
67+
5968
# Generate initial similarity metric
6069
free_cones = []
6170
marked_metric_params = holonomy.MarkedMetricParameters()

scripts/statistics.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -61,12 +61,13 @@ def run_statistics(args):
6161
m = fname[:dot_index]
6262
name = m
6363
models.append(m)
64+
mesh_output_dir = script_util.get_mesh_output_directory(args['output_dir'], m)
6465

6566
try:
6667
# Get mesh
6768
V, F = igl.read_triangle_mesh(os.path.join(args['input_dir'], fname))
68-
Th_hat = np.loadtxt(os.path.join(args['input_dir'], m + "_Th_hat"), dtype=float)
69-
rotation_form = np.loadtxt(os.path.join(args['input_dir'], m + "_kappa_hat"), dtype=float)
69+
Th_hat = np.loadtxt(os.path.join(mesh_output_dir, m + '_Th_hat'), dtype=float)
70+
rotation_form = np.loadtxt(os.path.join(mesh_output_dir, m + '_kappa_hat'), dtype=float)
7071

7172
# Generate metric TODO use constructor
7273
free_cones = []
@@ -85,7 +86,6 @@ def run_statistics(args):
8586

8687

8788
# get final metric coordinates
88-
mesh_output_dir = script_util.get_mesh_output_directory(args['output_dir'], m)
8989
metric_coords_path = os.path.join(mesh_output_dir, name + "_metric_coords")
9090
logger.info("Loading metric coordinates from {}".format(metric_coords_path))
9191
reduced_metric_coords = np.loadtxt(metric_coords_path)

src/holonomy/core/intrinsic_field.cpp

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1037,7 +1037,7 @@ VectorX IntrinsicNRosyField::compute_rotation_form(const Mesh<Scalar>& m)
10371037
std::queue<int> cones = {};
10381038
for (int vi = 0; vi < num_vertices; ++vi)
10391039
{
1040-
if (Th_hat[vi] < min_angle + 1e-6)
1040+
if (Th_hat[vi] < min_angle - 1e-6)
10411041
{
10421042
cones.push(vi);
10431043
}
@@ -1046,7 +1046,7 @@ VectorX IntrinsicNRosyField::compute_rotation_form(const Mesh<Scalar>& m)
10461046
{
10471047
int vi = cones.front();
10481048
cones.pop();
1049-
if (Th_hat[vi] > min_angle - 1e-6) continue;
1049+
if (Th_hat[vi] > min_angle + 1e-6) continue;
10501050
spdlog::info("Fixing {} cone at {} in rotation form", Th_hat[vi], vi);
10511051

10521052
// find largest cone angle near the cone vertex
@@ -1076,20 +1076,22 @@ VectorX IntrinsicNRosyField::compute_rotation_form(const Mesh<Scalar>& m)
10761076
// modify the rotation form and resulting cone angles
10771077
rotation_form[h_opt] -= (M_PI / 2.);
10781078
rotation_form[m.opp[h_opt]] += M_PI / 2.;
1079-
rotation_form[m.R[h_opt]] += M_PI / 2.;
1080-
rotation_form[m.opp[m.R[h_opt]]] -= M_PI / 2.;
1079+
if (m.type[h_opt] != 0) {
1080+
rotation_form[m.R[h_opt]] += M_PI / 2.;
1081+
rotation_form[m.opp[m.R[h_opt]]] -= M_PI / 2.;
1082+
}
10811083
Th_hat[vi] += M_PI / 2.;
10821084
Th_hat[vj] -= M_PI / 2.;
10831085

10841086
// check if candidate vertex is now a cone
1085-
if (Th_hat[vj] < min_angle + 1e-6)
1087+
if (Th_hat[vj] < min_angle - 1e-6)
10861088
{
10871089
cones.push(vj);
10881090
}
10891091
}
10901092

10911093
// check if vertex vi is still a cone
1092-
if (Th_hat[vi] < min_angle + 1e-6)
1094+
if (Th_hat[vi] < min_angle - 1e-6)
10931095
{
10941096
cones.push(vi);
10951097
}
@@ -1191,4 +1193,4 @@ polyscope::show();
11911193
}
11921194

11931195
} // namespace Holonomy
1194-
} // namespace Penner
1196+
} // namespace Penner

src/holonomy/core/viewer.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -797,6 +797,7 @@ void view_vertex_function(
797797
spdlog::info("Viewing {} mesh with {} vertices", mesh_handle, num_vertices);
798798
}
799799
auto [V_double, F_mesh, F_halfedge] = generate_doubled_mesh(V, m, vtx_reindex);
800+
if (num_vertices != vertex_function.size()) return;
800801

801802
#ifdef ENABLE_VISUALIZATION
802803
spdlog::debug("Initializing mesh");
@@ -860,4 +861,4 @@ void view_independent_vertex_function(
860861
}
861862

862863
} // namespace Holonomy
863-
} // namespace Penner
864+
} // namespace Penner

src/holonomy/holonomy/constraint.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -121,7 +121,7 @@ VectorX compute_vertex_constraint(
121121
{
122122
// Use all vertices
123123
std::vector<int> v_map = marked_metric.v_rep;
124-
int n_v = n_v = marked_metric.n_ind_vertices();
124+
int n_v = marked_metric.n_ind_vertices();
125125

126126
// Build the constraint
127127
VectorX constraint = VectorX::Zero(n_v);
@@ -390,4 +390,4 @@ void compute_metric_constraint_with_jacobian(
390390
}
391391

392392
} // namespace Holonomy
393-
} // namespace Penner
393+
} // namespace Penner

0 commit comments

Comments
 (0)