Title: | Smoothing of per-Vertex Data on Triangular Meshes |
---|---|
Description: | Smoothing of per-vertex data on triangular meshes, sub mesh creation based on vertex indices, per-vertex data interpolation based on k-d trees. |
Authors: | Tim Schäfer [aut, cre] |
Maintainer: | Tim Schäfer <[email protected]> |
License: | MIT + file LICENSE |
Version: | 0.2.0 |
Built: | 2024-11-03 03:20:35 UTC |
Source: | https://github.com/dfsp-spirit/haze |
Smoothing of per-vertex data on triangular meshes
This method uses inverse distance weight interpolation within a triangle. First, the face of the mesh
that the query_coordinate
falls into is determined. Then results in 3 vertices with respective per-vertex data, and a query coordinate. We then compute the distance to all 3 vertices, and perform inverse distance weight interpolation with a beta setting defined by parameter iwd_beta
.
linear_interpolate_kdtree( query_coordinates, mesh, pervertex_data, iwd_beta = 2, ... )
linear_interpolate_kdtree( query_coordinates, mesh, pervertex_data, iwd_beta = 2, ... )
query_coordinates |
nx3 numerical matrix of x,y,z coordinates. These are typically the vertex positions of a second (spherical!) mesh for that you need per-vertex data (e.g., the |
mesh |
fs.surface instance, see |
pervertex_data |
numerical vector, the continuous per-vertex data for the vertices of the mesh. |
iwd_beta |
scalar double, the |
... |
ignore, passed on to internal function |
named list with entries: 'interp_values', the numerical vector of interpolated data at the query_coordinates. 'nearest_vertex_in_face' the nearest vertex in the face that the respective query coordinate falls into, 'nearest_face' the index of the nearest face that the respective query coordinate falls into.
The mesh must be spherical, and the query_coordinates
must also be located on the mesh sphere.
Compute vertex neighborhoods for a mesh.
mesh.adj(surface, k = 1L)
mesh.adj(surface, k = 1L)
surface |
a mesh, represented as an |
k |
scalar positive integer, the k value for the k-ring neighborhood. For k=1, this function computes the adjacency list representation of the graph (where the neighbors include the vertex itself). |
list of integer vectors, the neighborhood data
## Not run: mesh = rgl::tetrahedron3d(); mesh_adj = mesh.adj(mesh, k = 1L); ## End(Not run)
## Not run: mesh = rgl::tetrahedron3d(); mesh_adj = mesh.adj(mesh, k = 1L); ## End(Not run)
Return pre-computed neighborhood data for specific meshes.
mesh.neigh.pre(meshname)
mesh.neigh.pre(meshname)
meshname |
a text identifier specifying the mesh you want connectivity data for. Currently supported meshes are listed here. 'lh_fsaverage': the left hemisphere of the FreeSurfer 6 fsaverage template. 'rh_fsaverage': the right hemisphere of the FreeSurfer 6 fsaverage template. 'lh_fsaverage6': the left hemisphere of the FreeSurfer 6 fsaverage6 template. 'rh_fsaverage6': the right hemisphere of the FreeSurfer 6 fsaverage6 template. |
list of vectors, the connectivity data as an adjacency list. The outer list has length n, where n is the number of vertices in the graph. The inner lists represent, for each vertex, all of its neighbors.
Return per-vertex data at the vertices closest to the given query points.
nn_interpolate_kdtree(query_coordinates, mesh, pervertex_data)
nn_interpolate_kdtree(query_coordinates, mesh, pervertex_data)
query_coordinates |
nx3 numerical matrix of x,y,z coordinates. These are typically the vertex positions of a second (spherical!) mesh for that you need per-vertex data (e.g., the |
mesh |
fs.surface instance, see |
pervertex_data |
numerical vector, the continuous per-vertex data for the vertices of the mesh. |
the per-vertex data for the vertices closest to the query coordinates.
Smooth per-vertex data based on mesh.
pervertexdata.smoothnn(surface, pvdata, num_iter, k = 1L, method = "C++")
pervertexdata.smoothnn(surface, pvdata, num_iter, k = 1L, method = "C++")
surface |
a mesh, represented as an |
pvdata |
numerical vector of per-vertex-data for the mesh, one value per vertex. Data values of |
num_iter |
positive integer, number of smoothing iterations. |
k |
scalar positive integer, the k value for the k-ring neighborhood. For k=1, this function computes the adjacency list representation of the graph (where the neighbors include the vertex itself). |
method |
character string, one of 'C++' or 'R'. The C++ version is much faster (about 30 times faster on our test machine), and there is little reason to ever use the R version in production code, so just ignore this. |
numerical vector, the smoothed data.
pervertexdata.smoothnn.adj
if you already have pre-computed adjacency data for the mesh. Using that data can increase performance considerably, especially if you need to smooth many data sets.
## Not run: mesh = rgl::tetrahedron3d(); pvd = rnorm(nrow(mes2$vb), mean = 5.0, sd = 1.0); pvd_smoothed = pervertexdata.smoothnn(mesh, pvd, num_iter = 30L); ## End(Not run)
## Not run: mesh = rgl::tetrahedron3d(); pvd = rnorm(nrow(mes2$vb), mean = 5.0, sd = 1.0); pvd_smoothed = pervertexdata.smoothnn(mesh, pvd, num_iter = 30L); ## End(Not run)
Smooth per-vertex data using nearest-neighbor smoothing based on mesh adjacency information.
pervertexdata.smoothnn.adj( mesh_adj, pvdata, num_iter, method = "C++", silent = getOption("haze.silent", default = TRUE) )
pervertexdata.smoothnn.adj( mesh_adj, pvdata, num_iter, method = "C++", silent = getOption("haze.silent", default = TRUE) )
mesh_adj |
list of vectors of integers, the adjacency list representation of the mesh. One can use the pre-computed adjacency for some special meshes, see |
pvdata |
numerical vector of per-vertex-data for the mesh, one value per vertex. Data values of |
num_iter |
positive integer, number of smoothing iterations. |
method |
character string, one of 'C++' or 'R'. The C++ version is much faster (about 30 times faster on our test machine), and there is little reason to ever use the R version in production code, so just ignore this. |
silent |
logical, whether to suppress output messages. |
numerical vector, the smoothed data (for vector input). If pvdata
is a matrix or a data.frame (with more than a single column), the result is also a matrix or data.frame.
pervertexdata.smoothnn
if you have a mesh and still need the connectivity to be computed.
## Not run: mesh = rgl::tetrahedron3d(); mesh_adj = mesh.adj(mesh, k = 1L); pvd = rnorm(nrow(mesh$vb), mean = 5.0, sd = 1.0); pvd_smoothed = pervertexdata.smoothnn.adj(mesh_adj, pvd, num_iter = 30L); ## End(Not run)
## Not run: mesh = rgl::tetrahedron3d(); mesh_adj = mesh.adj(mesh, k = 1L); pvd = rnorm(nrow(mesh$vb), mean = 5.0, sd = 1.0); pvd_smoothed = pervertexdata.smoothnn.adj(mesh_adj, pvd, num_iter = 30L); ## End(Not run)
Read matrix-like data from vv files. This is a custom format from the cpp_geodesic repo, designed to allow fast reading of vector-of-vectors data. The format does NOT require that all inner vectors have the same length, so it is NOT limited to matrices. The format is designed for storing graphs as adjacency lists.
read.vv(filepath)
read.vv(filepath)
filepath |
string. Full path to the input vv file. |
list of vectors, the data. The vv files may can store double or int, which is encoded in the file header and used accordingly.
Create a submesh including only the given vertices.
submesh.vertex(surface_mesh, old_vertex_indices_to_use, ret_mappings = FALSE)
submesh.vertex(surface_mesh, old_vertex_indices_to_use, ret_mappings = FALSE)
surface_mesh |
an |
old_vertex_indices_to_use |
integer vector, the vertex indices of the 'surface_mesh' that should be used to construct the new sub mesh. |
ret_mappings |
whether to return the vertex mappings. If |
the new mesh, made up of the given 'old_vertex_indices_to_use' and all (complete) faces that exist between the query vertices in the source mesh. But see 'ret_mapping' parameter.
## Not run: if(requireNamespace("fsbrain, quietly=T")) { sjd = fsbrain::fsaverage.path(T); sj = "fsaverage"; mesh = fsbrain::subject.surface(sjd, sj, hemi="lh"); lab = fsbrain::subject.label(sjd, sj, "cortex", hemi = "lh"); sm = submesh.vertex(mesh, lab); fsbrain::vis.fs.surface(mesh); # show the full mesh. fsbrain::vis.fs.surface(sm); # show only the cortex. } ## End(Not run)
## Not run: if(requireNamespace("fsbrain, quietly=T")) { sjd = fsbrain::fsaverage.path(T); sj = "fsaverage"; mesh = fsbrain::subject.surface(sjd, sj, hemi="lh"); lab = fsbrain::subject.label(sjd, sj, "cortex", hemi = "lh"); sm = submesh.vertex(mesh, lab); fsbrain::vis.fs.surface(mesh); # show the full mesh. fsbrain::vis.fs.surface(sm); # show only the cortex. } ## End(Not run)