% Generated by roxygen2: do not edit by hand
% Please edit documentation in R/vcg.R
\name{vcg_subdivide_max_edge_length}
\alias{vcg_subdivide_max_edge_length}
\title{Selectively subdivide mesh edges that exceed a length threshold}
\usage{
vcg_subdivide_max_edge_length(mesh, max_edge_len, max_iter = NULL)
}
\arguments{
\item{mesh}{triangular mesh of class \code{'mesh3d'}.}

\item{max_edge_len}{maximum allowed edge length (same units as mesh
coordinates).}

\item{max_iter}{maximum number of refinement passes. When \code{NULL}
(default), derived automatically from the current maximum edge length:
\code{ceiling(log2(current_max / max_edge_len)) + 1L}, the minimum number
of bisections needed in the worst case. The loop also terminates early once
no edge exceeds the threshold.}
}
\value{
An object of class \code{"mesh3d"} with all edges at most
  \code{max_edge_len} long (provided \code{max_iter} was sufficient).
}
\description{
Up-sample a triangular mesh by iteratively splitting only edges longer than
\code{max_edge_len}. Each long edge is split at its midpoint; the new vertex
is connected to the opposite corner of every adjacent face. Iteration stops
when no edge exceeds the threshold or \code{max_iter} passes are exhausted.

This is far cheaper than \code{\link{vcg_subdivision}} when most edges are
already short and only a small fraction need splitting.
}
\note{
The mesh must be manifold. Run \code{\link{vcg_fix_defects}} first if
  the mesh has boundary edges or non-manifold vertices.
}
\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()) {

  sphere <- vcg_sphere()
  cur_max <- vcg_max_edge_length(sphere)
  sphere2 <- vcg_subdivide_max_edge_length(sphere, max_edge_len = cur_max * 0.4)
  vcg_max_edge_length(sphere2)  # should be <= cur_max * 0.4

}

}
\seealso{
\code{\link{vcg_max_edge_length}}, \code{\link{vcg_subdivision}}
}
