\section{Lighting, Styling, and Filters} \label{sec:lighting-filters} The package keeps geometry generation separate from visual styling. Geometry keys determine what simplices exist; style keys determine how those simplices are drawn once the visibility pipeline is complete. \subsection{TikZ styling keys} Triangles use \verb|fill options|. Curves use \verb|draw options|. Labels use the literal node body given by \verb|text|. Because the package ultimately emits ordinary TikZ paths and nodes, these styling strings are plain TikZ option lists. \begin{Verbatim} fill options = {fill=ltdtbrightness, draw=black, line join=round} draw options = {draw=blue!70!black, ultra thick} \end{Verbatim} For triangles there is one package-specific convention worth remembering: if you want lights to affect a face, the fill style must actually reference \verb|ltdtbrightness|. The renderer computes that color dynamically from the current lights and the face normal. \subsection{Directional lights} Lights are appended by \verb|\appendlight| and supplied as vectors. The package normalizes those directions and computes a linear brightness factor from the angle between the light direction and the face normal. Multiple lights are averaged. \begin{Verbatim} \appendlight[ v = {return Vector:new{0.3, -0.2, 1, 1}} ] \appendlight[ v = {return Vector:new{-0.5, 0.4, 0.7, 1}} ] \end{Verbatim} The falloff is linear in the angle from $0^\circ$ to $90^\circ$, not cosine-based radiometry. That choice is intentional: it gives predictable illustrative shading without demanding a physically based material model. \input{figures/08-lighting-diagram.tex} \subsection{Filters} Every geometric append command accepts a \verb|filter| key. The filter is evaluated after partitioning, so it sees the pieces that will actually participate in the sort. That makes the filter mechanism more powerful than a simple pre-check on the original source geometry. The bound names depend on the simplex type: \begin{itemize}[leftmargin=2em] \item point-like and label entries bind \verb|A|; \item line segments bind \verb|A| and \verb|B|; \item triangles bind \verb|A|, \verb|B|, and \verb|C|. \end{itemize} Typical uses include removing back-facing slices, hiding geometry below a plane, or discarding pieces outside a region of interest. \begin{Verbatim} filter = { local normal = (B:hsub(A)):hhypercross(C:hsub(A)):hnormalize() return normal[3] > 0 } \end{Verbatim} \begin{Verbatim} filter = {return A[3] >= 0 and B[3] >= 0} \end{Verbatim} Because the filter sees the partitioned pieces, it can be used as a clean visual cutting tool without forcing the user to pre-split the source geometry manually. When a cut should land exactly on a visible boundary, a practical trick is to append an auxiliary surface that lies on the intended slicing boundary, let the partitioner split the target geometry against that surface, and then give the auxiliary surface \verb|filter = {return false}| so it disappears from the final render. \subsection{A style strategy that scales} For larger figures, it is usually best to settle on a small style vocabulary and reuse it consistently: \begin{itemize}[leftmargin=2em] \item triangles: \verb|fill=ltdtbrightness, draw=...|; \item curves: \verb|draw=...| through \verb|draw options|; \item special overlays: embedded surface curves with their own \verb|drawoptions|; \item annotations: labels without lighting. \end{itemize} This keeps the visual language clear and makes it easier to tune the lighting later without rewriting the geometry descriptions.