Skip to content

Commit 302e9ab

Browse files
ADD geodistance.
1 parent 73891d6 commit 302e9ab

File tree

5 files changed

+105
-6
lines changed

5 files changed

+105
-6
lines changed

docs/examples/geodistance.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
# ==============================================================================
2121

2222
source = trimesh.vertex_sample(size=1)[0]
23-
distance = igl.trimesh_geodistance(trimesh.to_vertices_and_faces(), source, method="heat")
23+
distance = igl.trimesh_geodistance(trimesh.to_vertices_and_faces(), source, method="exact")
2424

2525
# ==============================================================================
2626
# Visualize

src/compas.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,15 @@
2323
#include <Eigen/Geometry>
2424

2525
// libigl includes
26+
#include <igl/boundary_loop.h>
2627
#include <igl/cotmatrix.h>
2728
#include <igl/massmatrix.h>
2829
#include <igl/invert_diag.h>
2930
#include <igl/gaussian_curvature.h>
3031
#include <igl/principal_curvature.h>
31-
#include <igl/boundary_loop.h>
32+
#include <igl/avg_edge_length.h>
33+
#include <igl/exact_geodesic.h>
34+
#include <igl/heat_geodesics.h>
3235
#include <igl/map_vertices_to_circle.h>
3336
#include <igl/harmonic.h>
3437
#include <igl/doublearea.h>

src/compas_libigl/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from ._nanobind import add, __doc__
44
from .boundaries import trimesh_boundaries
55
from .curvature import trimesh_gaussian_curvature, trimesh_principal_curvature
6+
from .geodistance import trimesh_geodistance
67

78
# from .boundaries import trimesh_boundaries
89
# from .curvature import trimesh_gaussian_curvature, trimesh_principal_curvature
@@ -106,6 +107,7 @@ def get_armadillo():
106107
trimesh_boundaries,
107108
trimesh_gaussian_curvature,
108109
trimesh_principal_curvature,
110+
trimesh_geodistance,
109111
# "get",
110112
# "get_beetle",
111113
# "get_armadillo",

src/compas_libigl/geodistance.py

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import numpy as np
2+
from compas.plugins import plugin
3+
4+
from compas_libigl import _geodistance
5+
6+
7+
@plugin(category="trimesh")
8+
def trimesh_geodistance(M, source, method="exact"):
9+
"""Compute the geodesic distance from every vertex of the mesh to a source vertex.
10+
11+
Parameters
12+
----------
13+
M : (list, list)
14+
A mesh represented by a list of vertices and a list of faces.
15+
source : int
16+
The index of the vertex from where the geodesic distances should be calculated.
17+
method : {'exact', 'heat'}
18+
The method for calculating the distances.
19+
Default is `'exact'`.
20+
21+
Returns
22+
-------
23+
list of float
24+
A list of geodesic distances from the source vertex.
25+
26+
Raises
27+
------
28+
NotImplementedError
29+
If ``method`` is not one of ``{'exact', 'heat'}``.
30+
31+
Examples
32+
--------
33+
>>>
34+
35+
"""
36+
V, F = M
37+
V = np.asarray(V, dtype=np.float64)
38+
F = np.asarray(F, dtype=np.int32)
39+
if method == "exact":
40+
return _geodistance.trimesh_geodistance_exact(V, F, source)
41+
if method == "heat":
42+
return _geodistance.trimesh_geodistance_heat(V, F, source)
43+
raise NotImplementedError

src/geodistance.cpp

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

3-
void function(const Eigen::MatrixXd& V, const Eigen::MatrixXi& F) {}
3+
Eigen::VectorXd
4+
trimesh_geodistance_exact(
5+
const compas::RowMatrixXd& V,
6+
const compas::RowMatrixXi& F,
7+
int vid)
8+
{
9+
Eigen::VectorXd D;
10+
Eigen::VectorXi VS, FS, VT, FT;
11+
12+
VS.resize(1);
13+
VS << vid;
14+
15+
VT.setLinSpaced(V.rows(), 0, V.rows() - 1);
16+
17+
igl::exact_geodesic(V, F, VS, FS, VT, FT, D);
18+
19+
return D;
20+
}
21+
22+
Eigen::VectorXd
23+
trimesh_geodistance_heat(
24+
const compas::RowMatrixXd& V,
25+
const compas::RowMatrixXi& F,
26+
int vid)
27+
{
28+
Eigen::VectorXi gamma;
29+
gamma.resize(1);
30+
gamma << vid;
31+
32+
igl::HeatGeodesicsData<double> data;
33+
double t = std::pow(igl::avg_edge_length(V, F), 2);
34+
igl::heat_geodesics_precompute(V, F, t, data);
35+
36+
Eigen::VectorXd D = Eigen::VectorXd::Zero(data.Grad.cols());
37+
D(vid) = 1;
38+
39+
igl::heat_geodesics_solve(data, gamma, D);
40+
41+
return D;
42+
}
43+
44+
45+
446

547
NB_MODULE(_geodistance, m) {
648

749
m.def(
8-
"function_name",
9-
&function,
50+
"trimesh_geodistance_exact",
51+
&trimesh_geodistance_exact,
52+
"Description.",
53+
"V"_a,
54+
"F"_a,
55+
"vid"_a);
56+
57+
m.def(
58+
"trimesh_geodistance_heat",
59+
&trimesh_geodistance_heat,
1060
"Description.",
1161
"V"_a,
12-
"F"_a);
62+
"F"_a,
63+
"vid"_a);
1364
}

0 commit comments

Comments
 (0)