Nothing
#' Repair of a mesh
#' @description The \code{mesh.repair} function repairs holes in a \code{mesh}
#' class object.
#' @param mesh "mesh" class object.
#' @param verbose Boolean, by default set to \code{FALSE}. Allows you to inhibit
#' comments.
#' @return Returns a mesh, repaired by removing degenerated triangles and filling holes.
#' @examples
#' # loading of toy-patient objects (decrease dxyz for better result)
#' step <- 4
#' patient <- toy.load.patient(modality = c("ct", "rtstruct"),
#' roi.name = "gizzard", dxyz = rep(step, 3))
#' CT <- patient$ct[[1]]
#' S <- patient$rtstruct[[1]]
#'
#' # creation of the gizzard mesh
#' bin <- bin.from.roi(CT, struct = S, roi.name = "gizzard", verbose = FALSE)
#' mesh.gizzard <- mesh.from.bin(bin, alias = "gizzard", verbose = FALSE)
#'
#' repair.mesh.gizzard <- mesh.repair(mesh.gizzard, verbose = FALSE)
#' str(mesh.gizzard)
#' str(repair.mesh.gizzard)
#' @importFrom Rvcg vcgBorder vcgIsolated vcgSmooth vcgVFadj
#' @importFrom methods is
#' @export
mesh.repair <- function(mesh, verbose = TRUE) {
if (is.null(mesh)) return(NULL)
if (!is(mesh, "mesh")) stop("mesh should be a mesh class object.")
mesh_ <- mesh
mesh <- mesh_$mesh
##
## Removal of degenerate triangles
##
if (verbose) cat("mesh.repair INFO : removing degenerated triangles\n")
repeat {
## connection lists
f.list <- vcgVFadj(mesh) ## liste des triangles connectés à chaque vertex
v.list <- lapply(1:length(f.list), function(v) { ## liste des vertex connectés à chaque vertex
sel <- unique(as.vector(mesh$it[,f.list[[v]]]))
return(list(v = v, n.v = sel[sel != v]))
})
v <- sort(which(sapply(v.list, function(v) length(v$n.v)) == 2), decreasing = TRUE)[1]
if (is.na(v)) break
if (verbose) cat("mesh.repair INFO : cleaning", v, "\n")
mesh$vb <- mesh$vb[, -v]
t <- which(mesh$it == v, arr.ind = TRUE)[,2]
mesh$it <- mesh$it[, -t]
sel <- which(mesh$it > v)
mesh$it[sel] <- mesh$it[sel] - 1
mesh$normals <- mesh$remvert <- NULL
}
mesh <- vcgIsolated(mesh, silent = !verbose)
if (verbose) cat("mesh.repair INFO : removing 3 borders triangles\n")
borders <- vcgBorder(mesh)$bordervb
t.b <- apply(mesh$it, 2, function(t) !all(borders[t]))
if (verbose) cat("mesh.repair INFO : number of tr :", ncol(mesh$it) - sum(t.b) ,"\n")
mesh$it <- mesh$it[, t.b]
mesh$normals <- mesh$remvert <- NULL
mesh <- vcgIsolated(mesh, silent = !verbose)
if (verbose) cat("mesh.repair INFO : removing >2 borders border vertex\n")
repeat {
f.list <- vcgVFadj(mesh) ## list of triangles connected to each vertex
v.list <- lapply(1:length(f.list), function(v) { ## list of vertices connected to each vertex
sel <- unique(as.vector(mesh$it[,f.list[[v]]]))
return(list(v = v, n.v = sel[sel != v]))
})
borders <- vcgBorder(mesh)$bordervb
b.count <- sapply(which(borders), function(v) {
sum(borders[v.list[[v]]$n.v])
})
v <- sort(which(borders)[b.count > 2], decreasing = TRUE)[1]
if (is.na(v)) break
if (verbose) cat("mesh.repair INFO : cleaning", v, "\n")
mesh$vb <- mesh$vb[, -v]
t <- which(mesh$it == v, arr.ind = TRUE)[,2]
mesh$it <- mesh$it[, -t]
sel <- which(mesh$it > v)
mesh$it[sel] <- mesh$it[sel] - 1
mesh$normals <- mesh$remvert <- NULL
}
mesh <- vcgIsolated(mesh, silent = !verbose)
##
## repairing holes
##
if (verbose) cat("mesh.repair INFO : mesh holes filling\n")
## listes de connexions
f.list <- vcgVFadj(mesh)
v.list <- lapply(1:length(f.list), function(v) {
sel <- unique(as.vector(mesh$it[,f.list[[v]]]))
return(list(v = v, n.v = sel[sel != v]))
})
# table(sapply(f.list, function(v) length(v)))
# table(sapply(v.list, function(v) length(v$n.v)))
repeat {
borders <- vcgBorder(mesh)$bordervb
if (verbose) cat("mesh.repair INFO : remaining borders :", sum(borders), "\n")
b.list <- which(borders)[1]
if (is.na(b.list)) break
repeat {
if (rev(b.list)[1] %in% v.list[[b.list[1]]]$n.v & length(b.list) > 2) break
T1 <- which(mesh$it == b.list[1], arr.ind = TRUE)
for (Tr in T1[, 2]) {
id1 <- which(mesh$it[, Tr] == b.list[1])
id2 <- which(mesh$it[, Tr] != b.list[1] & borders[mesh$it[, Tr]])
if (length(id2) == 1) {
if (id1 == 1 & id2 == 3) break
if (id1 == 2 & id2 == 1) break
if (id1 == 3 & id2 == 2) break
} else if (length(id2) == 2) {
stop()
}
}
b.list <- c(mesh$it[id2, Tr], b.list)
}
G <- apply(mesh$vb[, b.list], 1, mean)
mesh$vb <- cbind(mesh$vb, G)
dimnames(mesh$vb) <- NULL
tr <- matrix(c(rep(ncol(mesh$vb), length(b.list)), b.list[-1], b.list[1], b.list), nrow = 3, byrow = TRUE)
mesh$it <- cbind(mesh$it, tr)
mesh$normals <- mesh$remvert <- NULL
f.list <- vcgVFadj(mesh)
v.list <- lapply(1:length(f.list), function(v) {
sel <- unique(as.vector(mesh$it[,f.list[[v]]]))
return(list(v = v, n.v = sel[sel != v]))
})
}
mesh_$mesh <- mesh
mesh_$nb.faces <- dim(mesh$it)[2]
class(mesh_)
return(mesh_)
}
Any scripts or data that you put into this service are public.
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.