Skip to content

Commit 1a76930

Browse files
ADD parametrisation.
1 parent e2ea10d commit 1a76930

File tree

5 files changed

+152
-12
lines changed

5 files changed

+152
-12
lines changed

docs/examples/parametrisation.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
# Least-squares conformal map
1818
# ==============================================================================
1919

20+
#lscm_uv = igl.trimesh_harmonic(mesh.to_vertices_and_faces())
2021
lscm_uv = igl.trimesh_lscm(mesh.to_vertices_and_faces())
2122

2223
for index, key in enumerate(mesh.vertices()):

src/compas.hpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,8 +24,8 @@
2424

2525
// libigl includes
2626
#include <igl/boundary_loop.h>
27+
2728
#include <igl/cotmatrix.h>
28-
#include <igl/massmatrix.h>
2929
#include <igl/invert_diag.h>
3030

3131
#include <igl/gaussian_curvature.h>
@@ -44,6 +44,10 @@
4444

4545
#include <igl/map_vertices_to_circle.h>
4646
#include <igl/harmonic.h>
47+
#include <igl/lscm.h>
48+
49+
#include <igl/planarize_quad_mesh.h>
50+
4751
#include <igl/doublearea.h>
4852
#include <igl/grad.h>
4953
#include <igl/per_vertex_normals.h>

src/compas_libigl/__init__.py

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,10 @@
77
from .intersections import intersection_ray_mesh, intersection_rays_mesh
88
from .isolines import trimesh_isolines, groupsort_isolines
99
from .massmatrix import trimesh_massmatrix
10+
from .parametrisation import trimesh_harmonic, trimesh_lscm
1011

11-
# from .meshing import trimesh_remesh_along_isoline
12-
# from .parametrisation import trimesh_harmonic, trimesh_lscm
1312
# from .planarize import quadmesh_planarize
13+
# from .meshing import trimesh_remesh_along_isoline
1414

1515

1616
__author__ = ["tom van mele", "petras vestartas"]
@@ -89,9 +89,9 @@ def get_armadillo():
8989
"compas_libigl.intersections",
9090
"compas_libigl.isolines",
9191
"compas_libigl.massmatrix",
92+
"compas_libigl.parametrisation",
93+
"compas_libigl.planarize",
9294
# "compas_libigl.meshing",
93-
# "compas_libigl.parametrisation",
94-
# "compas_libigl.planarize",
9595
]
9696

9797
__all__ = [
@@ -113,8 +113,8 @@ def get_armadillo():
113113
"trimesh_isolines",
114114
"groupsort_isolines",
115115
"trimesh_massmatrix",
116-
# "trimesh_remesh_along_isoline",
117-
# "trimesh_harmonic",
118-
# "trimesh_lscm",
116+
"trimesh_harmonic",
117+
"trimesh_lscm",
119118
# "quadmesh_planarize",
119+
# "trimesh_remesh_along_isoline",
120120
]
Lines changed: 82 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,82 @@
1+
import numpy as np
2+
from compas.plugins import plugin
3+
4+
from compas_libigl import _parametrisation
5+
6+
7+
@plugin(category="trimesh")
8+
def trimesh_harmonic(M):
9+
"""Compute the harmonic parametrisation of a triangle mesh within a fixed circular boundary.
10+
11+
Parameters
12+
----------
13+
M : tuple
14+
A mesh represented by a list of vertices and a list of faces
15+
or by a COMPAS mesh object.
16+
17+
Returns
18+
-------
19+
array
20+
The u, v parameters per vertex.
21+
22+
Examples
23+
--------
24+
>>> import compas_libigl as igl
25+
>>> from compas.datastructures import Mesh
26+
>>> mesh = Mesh.from_off(igl.get("camelhead.off"))
27+
>>> mesh_uv = mesh.copy()
28+
>>> mesh_uv.vertices_attribute("z", 0)
29+
>>> M = mesh.to_vertices_and_faces()
30+
>>> uv = igl.trimesh_harmonic(M)
31+
>>> for key in mesh.vertices():
32+
... mesh_uv.vertex_attributes(key, "xy", uv[key])
33+
>>>
34+
35+
Notes
36+
-----
37+
``camelhead.off`` can be downloaded from https://raw.githubusercontent.com/libigl/libigl-tutorial-data/master/camelhead.off
38+
39+
"""
40+
V, F = M
41+
V = np.asarray(V, dtype=np.float64)
42+
F = np.asarray(F, dtype=np.int32)
43+
return _parametrisation.harmonic(V, F)
44+
45+
46+
@plugin(category="trimesh")
47+
def trimesh_lscm(M):
48+
"""Compute the least squares conformal map of a triangle mesh.
49+
50+
Parameters
51+
----------
52+
M : tuple
53+
A mesh represented by a list of vertices and a list of faces
54+
or by a COMPAS mesh object.
55+
56+
Returns
57+
-------
58+
array
59+
The u, v parameters per vertex.
60+
61+
Examples
62+
--------
63+
>>> import compas_libigl as igl
64+
>>> from compas.datastructures import Mesh
65+
>>> mesh = Mesh.from_off(igl.get("camelhead.off"))
66+
>>> mesh_uv = mesh.copy()
67+
>>> mesh_uv.vertices_attribute("z", 0)
68+
>>> M = mesh.to_vertices_and_faces()
69+
>>> uv = igl.trimesh_lscm(M)
70+
>>> for key in mesh.vertices():
71+
... mesh_uv.vertex_attributes(key, "xy", uv[key])
72+
>>>
73+
74+
Notes
75+
-----
76+
``camelhead.off`` can be downloaded from https://raw.githubusercontent.com/libigl/libigl-tutorial-data/master/camelhead.off
77+
78+
"""
79+
V, F = M
80+
V = np.asarray(V, dtype=np.float64)
81+
F = np.asarray(F, dtype=np.int32)
82+
return _parametrisation.lscm(V, F)

src/parametrisation.cpp

Lines changed: 57 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,66 @@
11
#include "parametrisation.hpp"
22

3-
void function(const compas::RowMatrixXd& V, const compas::RowMatrixXi& F) {}
3+
4+
Eigen::MatrixXd
5+
harmonic(
6+
const compas::RowMatrixXd& V,
7+
const compas::RowMatrixXi& F)
8+
{
9+
Eigen::MatrixXd V_uv;
10+
11+
// Find the open boundary
12+
Eigen::VectorXi B;
13+
igl::boundary_loop(F, B);
14+
15+
// Map the boundary to a circle, preserving edge proportions
16+
Eigen::MatrixXd B_uv;
17+
igl::map_vertices_to_circle(V, B, B_uv);
18+
19+
// Harmonic parametrization for the internal vertices
20+
igl::harmonic(V, F, B, B_uv, 1, V_uv);
21+
22+
return V_uv;
23+
}
24+
25+
26+
Eigen::MatrixXd
27+
lscm(
28+
const compas::RowMatrixXd& V,
29+
const compas::RowMatrixXi& F)
30+
{
31+
Eigen::MatrixXd V_uv;
32+
33+
// Find the open boundary
34+
Eigen::VectorXi B;
35+
igl::boundary_loop(F, B);
36+
37+
// Fix two points on the boundary
38+
Eigen::VectorXi fixed(2, 1);
39+
fixed(0) = B(0);
40+
fixed(1) = B(B.size() / 2);
41+
42+
Eigen::MatrixXd fixed_uv(2, 2);
43+
fixed_uv << 0, 0, 1, 0;
44+
45+
// LSCM parametrization
46+
igl::lscm(V, F, fixed, fixed_uv, V_uv);
47+
48+
return V_uv;
49+
}
450

551
NB_MODULE(_parametrisation, m) {
652

753
m.def(
8-
"function_name",
9-
&function,
10-
"Description.",
54+
"harmonic",
55+
&harmonic,
56+
"Compute the harmonic parametrization of a triangle mesh.",
57+
"V"_a,
58+
"F"_a);
59+
60+
m.def(
61+
"lscm",
62+
&lscm,
63+
"Compute the least-squares conformal map of a triangle mesh.",
1164
"V"_a,
1265
"F"_a);
1366
}

0 commit comments

Comments
 (0)