% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/imaging-fill-surface.R
\name{ensure_mesh3d}
\alias{ensure_mesh3d}
\title{Coerce a surface object to a \code{'mesh3d'} mesh}
\usage{
ensure_mesh3d(surface)
}
\arguments{
\item{surface}{a surface object. One of the following:
\describe{
  \item{\code{'mesh3d'}}{returned unchanged.}
  \item{\code{'fs.surface'}}{a surface in the format produced by
    \code{freesurferformats::read.fs.surface}. Vertices and faces are
    copied into a \code{'mesh3d'} list; zero-indexed faces are bumped
    by 1.}
  \item{\code{'ieegio_surface'}}{a surface object produced by
    \pkg{ieegio} (e.g. from \code{read_surface} or
    \code{volume_to_surface}). See the section below for important
    behavior changes.}
  \item{a bare \code{list}}{must contain a numeric \code{vb} matrix with
    3 or 4 rows; the list is reclassified as \code{'mesh3d'} with no
    other modification.}
}
Any other input triggers an error.}
}
\value{
An object of class \code{'mesh3d'} with at least the \code{vb}
(vertex) component and, when face information is available, an \code{it}
(triangle index) component.
}
\description{
Internal helper used throughout \pkg{ravetools} to accept a variety of
surface representations and return a list of class \code{'mesh3d'} (the
format used by the \code{rgl} package). Most mesh-consuming functions in
this package call \code{ensure_mesh3d} on their surface arguments, so the
coercion rules described here apply to all of them.
}
\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{

# mesh3d input is returned unchanged in shape
sphere <- vcg_sphere()
m <- ensure_mesh3d(sphere)
identical(m$vb, sphere$vb)

# A bare list with a `vb` slot is reclassified to mesh3d
bare <- list(vb = rbind(matrix(rnorm(30), nrow = 3), 1))
m <- ensure_mesh3d(bare)
inherits(m, "mesh3d")

}
