% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/vcg.R
\name{vcg_smooth}
\alias{vcg_smooth}
\alias{vcg_smooth_implicit}
\alias{vcg_smooth_explicit}
\title{Implicitly smooth a triangular mesh}
\usage{
vcg_smooth_implicit(
  mesh,
  lambda = 0.2,
  use_mass_matrix = TRUE,
  fix_border = FALSE,
  use_cot_weight = FALSE,
  degree = 1L,
  laplacian_weight = 1
)

vcg_smooth_explicit(
  mesh,
  type = c("taubin", "laplace", "HClaplace", "fujiLaplace", "angWeight",
    "surfPreserveLaplace"),
  iteration = 10,
  lambda = 0.5,
  mu = -0.53,
  delta = 0.1
)
}
\arguments{
\item{mesh}{triangular mesh stored as object of class 'mesh3d'.}

\item{lambda}{In \code{vcg_smooth_implicit}, the amount of smoothness,
useful only if \code{use_mass_matrix} is \code{TRUE}; default is \code{0.2}.
In \code{vcg_smooth_explicit}, parameter for \code{'taubin'} smoothing.}

\item{use_mass_matrix}{logical: whether to use mass matrix to keep the mesh
close to its original position (weighted per area distributed on vertices);
default is \code{TRUE}}

\item{fix_border}{logical: whether to fix the border vertices of the mesh;
default is \code{FALSE}}

\item{use_cot_weight}{logical: whether to use cotangent weight; default is
\code{FALSE} (using uniform 'Laplacian')}

\item{degree}{integer: degrees of 'Laplacian'; default is \code{1}}

\item{laplacian_weight}{numeric: weight when \code{use_cot_weight} is \code{FALSE};
default is \code{1.0}}

\item{type}{method name of explicit smooth, choices are \code{'taubin'},
\code{'laplace'}, \code{'HClaplace'}, \code{'fujiLaplace'},
\code{'angWeight'}, \code{'surfPreserveLaplace'}.}

\item{iteration}{number of iterations}

\item{mu}{parameter for \code{'taubin'} explicit smoothing.}

\item{delta}{parameter for scale-dependent 'Laplacian' smoothing or
maximum allowed angle (in 'Radian') for deviation between surface preserving
'Laplacian'.}
}
\value{
An object of class "mesh3d" with:
\item{\code{vb}}{vertex coordinates}
\item{\code{normals}}{vertex normal vectors}
\item{\code{it}}{triangular face index}
}
\description{
Applies smoothing algorithms on a triangular mesh.
}
\section{Coercing Surface Inputs}{

The surface objects are converted to \code{'mesh3d'} object before
applying further calculations.

When \code{surface} is a surface \pkg{ieegio} object, the returned
\code{mesh3d$vb} contains vertices that have been left-multiplied by
\code{surface$geometry$transforms[[1]]} (the first transform stored in the
geometry, typically the \code{ScannerAnat} or voxel-to-world transform).

\strong{Breaking change:} Earlier versions (before 0.2.6) of \pkg{ravetools}
returned the raw \code{surface$geometry$vertices} without applying any
transform, so downstream code often multiplied by
\code{surface$geometry$transforms[[1]]} (or an equivalent) manually before
working in world space. Such code will now \emph{double}
apply the transform and produce incorrect coordinates. If you previously
applied a transform from \code{surface$geometry$transforms} by hand after
calling a \pkg{ravetools} mesh function on an \code{'ieegio_surface'},
remove that manual step.

Surfaces with an empty or missing \code{geometry$transforms} list (for
example, surfaces produced by \pkg{ieegio}'s \code{volume_to_surface},
which stores an identity transform) are unaffected.

If \code{geometry$transforms} contains multiple transforms targeting
different coordinate spaces, only the first one is used. Callers that need
a specific target space should select and apply that transform themselves
before calling \pkg{ravetools} mesh functions.
}

\examples{

if(is_not_cran()) {

# Prepare mesh with no normals
data("left_hippocampus_mask")

# Grow 2mm on each direction to fill holes
volume <- grow_volume(left_hippocampus_mask, 2)

# Initial mesh
mesh <- vcg_isosurface(volume)

# Start: examples
rgl_view({
  rgl_call("mfrow3d", 2, 4)
  rgl_call("title3d", "Naive ISOSurface")
  rgl_call("shade3d", mesh, col = 2)

  rgl_call("next3d")
  rgl_call("title3d", "Implicit Smooth")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_implicit(mesh, degree = 2))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - taubin")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "taubin"))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - laplace")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "laplace"))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - angWeight")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "angWeight"))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - HClaplace")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "HClaplace"))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - fujiLaplace")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "fujiLaplace"))

  rgl_call("next3d")
  rgl_call("title3d", "Explicit Smooth - surfPreserveLaplace")
  rgl_call("shade3d", col = 2,
           x = vcg_smooth_explicit(mesh, "surfPreserveLaplace"))
})

}

}
