| Type: | Package |
| Title: | Headless Publication-Quality 3D Mesh Rendering Engine |
| Version: | 0.3.0 |
| Description: | A fast, GPU-free 3D software renderer written in modern C++17 with native R bindings. Renders triangle meshes to publication-quality images entirely on the CPU, requiring no display server or graphics hardware. Features multi-light Blinn-Phong shading, screen-space ambient occlusion, anti-aliasing, depth fog, transparency, wireframe rendering, texture mapping, and procedural geometry generation. Supports standard mesh file formats with PNG and PPM output. Works on high-performance computing clusters, headless servers, containers, and continuous integration pipelines, making it suitable for scientific visualization across neuro-imaging, molecular structures, and general 3D graphics. |
| License: | MIT + file LICENSE |
| URL: | https://github.com/dfsp-spirit/scimesh |
| BugReports: | https://github.com/dfsp-spirit/scimesh/issues |
| Imports: | Rcpp (≥ 1.0.0) |
| LinkingTo: | Rcpp |
| Suggests: | testthat (≥ 3.0.0), png, freesurferformats, viridisLite, knitr, rmarkdown |
| VignetteBuilder: | knitr |
| SystemRequirements: | C++17 |
| Config/testthat/edition: | 3 |
| Encoding: | UTF-8 |
| NeedsCompilation: | yes |
| Config/roxygen2/version: | 8.0.0 |
| RoxygenNote: | 7.3.3 |
| Packaged: | 2026-08-03 13:33:29 UTC; timschaefer |
| Author: | Tim Schäfer [aut, cre], Martin Hořeňovský [ctb] (Author of Catch2 (cpp_tests/catch_amalgamated.{h,cpp})), Christophe Riccio [ctb] (Author of GLM - OpenGL Mathematics (src/third_party/glm/)), Dimitri Diakopoulos [ctb] (Author of tinyply (src/third_party/tinyply.{h,cpp})), Syoyo Fujita [ctb] (Author of tinyobjloader (src/third_party/tiny_obj_loader.h)), Tim Schäfer [ctb] (Author of libfs (src/third_party/libfs.h)), Sebastian Reiter [ctb] (Author of stl_reader (src/third_party/stl_reader.h)), Sean Barrett [ctb] (Author of stb libraries (src/third_party/stb_image*.h)) |
| Maintainer: | Tim Schäfer <ts+code@rcmd.org> |
| Repository: | CRAN |
| Date/Publication: | 2026-08-09 07:00:02 UTC |
Apply a colormap to numerical data
Description
Maps numeric per-vertex (or per-element) data to RGBA colours using a colormap. Handles multi-dataset data (e.g., two brain hemispheres), NaN values, and optional outlier clipping via winsorizing.
Usage
apply_colormap(
data,
colormap = viridis_colormap(256L),
limits = NULL,
nan_color = c(0.5, 0.5, 0.5, 1),
winsor_percentiles = NULL
)
Arguments
data |
A numeric vector, or a list of numeric vectors for multi-dataset mapping (e.g., list(lh_data, rh_data)). |
colormap |
A colormap specification: a function f(n) returning n hex colour strings (e.g., viridis_colormap), a character vector of hex colours, or an Nx3/Nx4 matrix of RGBA values in [0,1]. Default is viridis_colormap(256L). |
limits |
How the data value range is determined. NULL (default) auto-detects from finite values after winsorizing. c(min, max) sets an explicit fixed range. "global" pools all datasets for a shared range. "each" uses independent per-dataset ranges. |
nan_color |
RGBA colour for NaN/NA values as a length-3 (RGB) or length-4 (RGBA) numeric vector in [0,1]. Default mid-grey. |
winsor_percentiles |
Optional c(lower, upper) percentiles for outlier clipping, e.g. c(0.02, 0.98). NULL disables winsorizing. |
Value
If data is a single vector: an Nx4 numeric matrix of RGBA colours. If data is a list: a list of Nx4 matrices.
Attributes on the result provide metadata. Single-dataset: data_min, data_max, raw_min, raw_max, winsor_lo, winsor_hi, nan_count. Multi-dataset: pooled_data_min, pooled_data_max (use for a colourbar), data_ranges, winsor_cutoffs, nan_counts.
Examples
data <- c(1.2, 3.4, NA, 2.1, 5.0, 2.8)
colors <- apply_colormap(data)
noisy <- c(rnorm(95, mean = 50, sd = 10), 200, -50)
colors <- apply_colormap(noisy, winsor_percentiles = c(0.02, 0.98))
lh <- c(2.3, 2.1, NA, 3.4)
rh <- c(2.5, 2.0, NA, 3.1)
colors <- apply_colormap(list(lh, rh),
colormap = viridis_colormap(256L),
limits = "global",
winsor_percentiles = c(0.02, 0.98),
nan_color = c(1, 1, 1, 1))
Convert rgl or scimesh mesh to canonical scimesh format
Description
Internal helper that transparently accepts either an rgl-style mesh
(list with vb/it) or a scimesh mesh descriptor
(list with vertices/triangles) and returns the
canonical scimesh format.
Usage
as_scimesh_mesh(x)
Arguments
x |
A mesh-like object (rgl tmesh3d or scimesh mesh descriptor). |
Value
A scimesh mesh descriptor list with vertices and
triangles.
Create a camera specification
Description
Defines a camera for rendering by specifying the eye position, look-at center, up vector, projection type, and field of view.
Usage
camera(
eye,
center,
up = c(0, 1, 0),
projection = c("perspective", "orthographic"),
fov = 45
)
Arguments
eye |
Numeric vector of length 3: camera position. |
center |
Numeric vector of length 3: point the camera looks at. |
up |
Numeric vector of length 3: camera up direction. |
projection |
Projection type: |
fov |
Field of view in degrees (perspective only). |
Value
A camera list suitable for render_mesh() or
render_scene().
Examples
cam <- camera(eye = c(0, 0, 5), center = c(0, 0, 0))
cam$eye
Auto-frame a camera to fit a mesh or vertex set
Description
Computes a camera position that frames the entire mesh in view. The camera looks along the given direction, positioned at a distance that ensures the mesh fits within the field of view.
Usage
camera_auto(
mesh,
direction = c(0, 0, -1),
up = c(0, 1, 0),
fov = 45,
margin = 1.1,
rgl_compat = FALSE,
projection = c("perspective", "orthographic")
)
Arguments
mesh |
Either an Nx3 numeric matrix of vertex positions, or a
mesh descriptor list with a |
direction |
The view direction as a length-3 vector. For
example, |
up |
The up vector as a length-3 vector. Default |
fov |
Field of view in degrees. Default 45° (30° when
|
margin |
Extra margin factor (1.0 = tight fit, 1.1 = 10% margin). |
rgl_compat |
Logical. If |
projection |
Projection type: |
Details
When rgl_compat = TRUE, the camera mimics rgl's default
auto-framing behaviour: a 30° FOV, 15° elevation, and the distance
is computed from the bounding sphere of the mesh (the
half-diagonal of the axis-aligned bounding box), reproducing the
formula distance = sphere_radius / sin(FOV/2) used by rgl.
Value
A camera list, with S3 class "scimesh_camera".
Examples
verts <- matrix(c(-1,-1,-1, 1,-1,-1, 1,1,-1, -1,1,-1,
-1,-1, 1, 1,-1, 1, 1,1, 1, -1,1, 1), ncol = 3, byrow = TRUE)
tris <- matrix(c(0L,3L,2L, 0L,2L,1L, 4L,5L,6L, 4L,6L,7L,
0L,1L,5L, 0L,5L,4L, 2L,3L,7L, 2L,7L,6L,
0L,4L,7L, 0L,7L,3L, 1L,2L,6L, 1L,6L,5L), ncol = 3, byrow = TRUE)
mesh <- list(vertices = verts, triangles = tris)
cam <- camera_auto(mesh, direction = c(1, 1, 1))
cam_rgl <- camera_auto(mesh, rgl_compat = TRUE)
Orbit a camera around an axis
Description
Rotates a camera's eye position and up vector around its center by a given angle about a rotation axis. Useful for generating turntable-style frame sequences.
Usage
camera_orbit(camera, axis = c(0, 0, 1), angle_degrees)
Arguments
camera |
A camera list from |
axis |
Rotation axis as a length-3 vector. Default |
angle_degrees |
Rotation angle in degrees. |
Value
A camera list with S3 class "scimesh_camera".
Examples
mesh <- generate_torus(c(0, 0, 0))
cam <- camera_auto(mesh, direction = c(1, 1, 1))
cam2 <- camera_orbit(cam, axis = c(0, 0, 1), angle_degrees = 90)
Generate a horizontal colorbar image
Description
Creates a horizontal colorbar as a 4-channel RGBA array. The color
strip and optional tick labels are rendered to PNG using base R
graphics (headless-safe). Returns a 3D array suitable for
image_to_array() or direct composition.
Usage
colorbar_horizontal(
colormap,
n_colors = 256L,
width = 600L,
height = 80L,
ticks = NULL,
tick_labels = NULL,
data_range = c(0, 1),
label_cex = 1,
title = NULL,
background = c(1, 1, 1, 1)
)
Arguments
colormap |
A vector of colors or a function returning colors
(e.g. |
n_colors |
Number of discrete color segments in the gradient. |
width |
Output width in pixels. |
height |
Output height in pixels. |
ticks |
Numeric vector of tick positions in data units
(matching |
tick_labels |
Character vector of tick labels. If |
data_range |
The data range that |
label_cex |
Label size multiplier. |
title |
Optional title string drawn above the color strip (horizontal) or to the right (vertical). |
background |
Background RGBA color (0-1 scale). |
Value
A 3D array of dimensions (height, width, 4) with values in
[0, 1].
Examples
cbar <- colorbar_horizontal(viridis_colormap, data_range = c(-2, 3),
title = "Value")
dim(cbar) # height x width x 4
Generate a vertical colorbar image
Description
Creates a vertical colorbar as a 4-channel RGBA array.
Usage
colorbar_vertical(
colormap,
n_colors = 256L,
width = 80L,
height = 600L,
ticks = NULL,
tick_labels = NULL,
data_range = c(0, 1),
label_cex = 1,
title = NULL,
background = c(1, 1, 1, 1)
)
Arguments
colormap |
A vector of colors or a function returning colors. |
n_colors |
Number of discrete color segments in the gradient. |
width |
Output width in pixels. |
height |
Output height in pixels. |
ticks |
Numeric vector of tick positions in data units.
If |
tick_labels |
Character vector of tick labels. |
data_range |
The data range that |
label_cex |
Label size multiplier. |
title |
Optional title string drawn to the right of the color strip. |
background |
Background RGBA color (0-1 scale). |
Value
A 3D array of dimensions (height, width, 4) with values in
[0, 1].
Examples
cbar <- colorbar_vertical(viridis_colormap, data_range = c(0, 100),
title = "Count")
dim(cbar)
Compose multiple images into a single figure
Description
Arranges rendered images (from render_mesh() or
render_scene()) into a grid layout and optionally appends
a colorbar. All composition is done with pure R array operations.
Usage
compose_layout(
images,
nrow = NULL,
ncol = NULL,
colorbar = NULL,
colorbar_height = 80L,
colorbar_width = 80L,
background = c(0, 0, 0, 0),
colorbar_side = c("right", "left"),
crop = FALSE
)
Arguments
images |
A list of images, each a list with |
nrow |
Number of rows in the grid layout. |
ncol |
Number of columns in the grid layout. If both
|
colorbar |
Optional colorbar array (from
|
colorbar_height |
Height of the colorbar row in pixels. Only used when appending a horizontal colorbar. |
colorbar_width |
Width of the colorbar column in pixels. Only used when appending a vertical colorbar. |
background |
Background RGBA color for padding (0-1 scale). |
colorbar_side |
For vertical colorbars, whether to place
the bar on the |
crop |
Logical. If |
Value
A list with width, height, pixels
suitable for write_png() or image_to_array().
Examples
mesh1 <- generate_cuboid(c(-1.5, 0, 0), c(0.5, 0.5, 0.5), c(1, 0, 0, 1))
mesh2 <- generate_cuboid(c( 1.5, 0, 0), c(0.5, 0.5, 0.5), c(0, 0, 1, 1))
img1 <- render_mesh(mesh1$vertices, mesh1$triangles)
img2 <- render_mesh(mesh2$vertices, mesh2$triangles)
result <- compose_layout(list(img1, img2), nrow = 1L)
tmp_file <- tempfile(fileext = ".png")
write_png(result, tmp_file)
Compute per-vertex normals for a mesh
Description
Computes smooth vertex normals by averaging face normals. Returns
the same mesh with a normals component (Nx3 numeric matrix).
Useful for imported meshes that lack pre-computed normals.
Usage
compute_vertex_normals(mesh)
Arguments
mesh |
A mesh descriptor list with |
Value
The mesh with a normals component added.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
mesh <- compute_vertex_normals(mesh)
nrow(mesh$normals)
Custom diverging colormap for neuroimaging
Description
Returns a blue-white-red diverging colormap suitable for displaying signed morphometry data (e.g. cortical thickness Z-scores).
Usage
diverging_colormap(n)
Arguments
n |
Number of colors. |
Value
A character vector of hex color strings.
Examples
cols <- diverging_colormap(256)
plot(1:256, pch = 15, col = cols, cex = 2, axes = FALSE, xlab = "", ylab = "")
Generate an arrow mesh
Description
Creates a 3D arrow from from to to, with a cylindrical
shaft and a conical head.
Usage
generate_arrow(
from,
to,
shaft_radius = 0.1,
head_radius = 0.3,
head_length = 0.6,
segments = 32,
color = c(1, 1, 1, 1)
)
Arguments
from |
Length-3 start point. |
to |
Length-3 end point (tip of the arrowhead). |
shaft_radius |
Radius of the shaft cylinder. |
head_radius |
Radius at the base of the conical head. |
head_length |
Length of the arrowhead. |
segments |
Subdivision count (default 32). |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_arrow(c(0, 0, 0), c(0, 2, 0))
nrow(mesh$vertices)
Generate XYZ axis arrows as cylinder meshes
Description
Creates three coloured arrow meshes (red X, green Y, blue Z) from a centre point.
Usage
generate_axes(center = c(0, 0, 0), size = 1, shaft_radius = 0.02)
Arguments
center |
Length-3 vector: origin of the axes. |
size |
Length of each axis. |
shaft_radius |
Cylinder radius for axis shafts. |
Value
A mesh descriptor list suitable for render_mesh()
or inclusion in a scene list.
Examples
axes_mesh <- generate_axes(size = 2)
nrow(axes_mesh$vertices)
Generate a wireframe bounding box mesh
Description
Creates 12 edge segments around an axis-aligned bounding box.
Usage
generate_bbox(bbox, color = c(0, 0, 0, 1), radius = 0.01)
Arguments
bbox |
A bounding box list from |
color |
RGBA colour for the edges (length 4, 0-1 scale). |
radius |
Cylinder radius for the edges. |
Value
A mesh descriptor list suitable for render_mesh()
or inclusion in a scene list.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 2, 3))
bbox_mesh <- generate_bbox(mesh)
nrow(bbox_mesh$vertices)
Generate a cone mesh
Description
Creates a cone from base to tip with the given base
radius, subdivided into segments around the axis.
The base cap is included.
Usage
generate_cone(base, tip, radius = 0.5, segments = 32, color = c(1, 1, 1, 1))
Arguments
base |
Length-3 vector: centre of the circular base. |
tip |
Length-3 vector: tip of the cone. |
radius |
Base radius. |
segments |
Subdivision count (default 32). |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_cone(c(0, -1, 0), c(0, 1, 0), radius = 0.8)
nrow(mesh$vertices)
Generate a cuboid mesh
Description
Creates an axis-aligned cuboid (box) centred at center
with the given half-extents along each axis.
Usage
generate_cuboid(center, half_extents, color = c(0.7, 0.7, 0.7, 1))
Arguments
center |
Length-3 vector: centre of the cuboid. |
half_extents |
Length-3 vector: half-width, half-height, half-depth. |
color |
Length-4 RGBA colour (0-1 scale). |
Value
A mesh descriptor list.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 2, 0.5))
nrow(mesh$vertices)
nrow(mesh$triangles)
Generate a cylinder mesh
Description
Creates a cylinder from start to end with the given
radius, subdivided into segments around the axis.
Both end caps are included.
Usage
generate_cylinder(
start,
end,
radius = 0.5,
segments = 32,
color = c(1, 1, 1, 1)
)
Arguments
start |
Length-3 vector: cylinder start point. |
end |
Length-3 vector: cylinder end point. |
radius |
Cylinder radius. |
segments |
Subdivision count (default 32). |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_cylinder(c(0, -1, 0), c(0, 1, 0), radius = 0.5)
nrow(mesh$vertices)
Generate a planar quad mesh
Description
Creates a flat rectangular plane centred at center and
oriented perpendicular to normal.
Usage
generate_plane(
center = c(0, 0, 0),
normal = c(0, 1, 0),
half_size_x = 1,
half_size_y = 1,
color = c(0.7, 0.7, 0.7, 1)
)
Arguments
center |
Length-3 vector: centre of the plane. |
normal |
Length-3 vector: surface normal. |
half_size_x |
Half-extent along the first tangent axis. |
half_size_y |
Half-extent along the second tangent axis. |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_plane(c(0, 0, 0), normal = c(0, 1, 0),
half_size_x = 2, half_size_y = 1)
nrow(mesh$vertices)
Generate a square pyramid mesh
Description
Creates a pyramid with a square base centred at base_center
in the XZ plane, with the apex above it along Y.
Usage
generate_pyramid(
base_center,
apex,
half_width = 1,
color = c(0.7, 0.7, 0.7, 1)
)
Arguments
base_center |
Length-3 vector: centre of the square base. |
apex |
Length-3 vector: position of the tip. |
half_width |
Half-width of the square base. |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_pyramid(c(0, 0, 0), c(0, 2, 0), half_width = 1)
mesh$vertices
Generate a sphere mesh
Description
Creates a UV sphere centred at center with the given
radius. The sphere is subdivided into segments
rings and segments per ring.
Usage
generate_sphere(center, radius = 1, segments = 32, color = c(1, 1, 1, 1))
Arguments
center |
Length-3 vector: sphere centre. |
radius |
Sphere radius. |
segments |
Subdivision count (default 32). |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_sphere(c(0, 0, 0), radius = 1.5, segments = 32)
nrow(mesh$vertices)
Generate a tetrahedron mesh
Description
Creates a tetrahedron (triangular pyramid) from four arbitrary 3D points.
Usage
generate_tetrahedron(p0, p1, p2, p3, color = c(0.7, 0.7, 0.7, 1))
Arguments
p0 |
Length-3 vector: first vertex. |
p1 |
Length-3 vector: second vertex. |
p2 |
Length-3 vector: third vertex. |
p3 |
Length-3 vector: fourth vertex. |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_tetrahedron(
c(0, 0, 0), c(1, 0, 0),
c(0.5, 1, 0), c(0.5, 0.5, 1))
nrow(mesh$vertices)
Generate a torus mesh
Description
Creates a torus (donut shape) centred at center, lying in
the XZ plane.
Usage
generate_torus(
center = c(0, 0, 0),
major_radius = 1,
minor_radius = 0.3,
major_segments = 32,
minor_segments = 16,
color = c(0.7, 0.7, 0.7, 1)
)
Arguments
center |
Length-3 vector: centre of the torus. |
major_radius |
Radius of the ring (tube path). |
minor_radius |
Radius of the tube cross-section. |
major_segments |
Number of segments around the ring. |
minor_segments |
Number of segments around the tube. |
color |
Length-4 RGBA colour. |
Value
A mesh descriptor list.
Examples
mesh <- generate_torus(major_radius = 2, minor_radius = 0.5)
nrow(mesh$vertices)
Apply contrast adjustment to an image
Description
Applies a contrast stretch (S-curve) to the RGB channels of a
rendered image. Formula: (value - 0.5) * contrast + 0.5,
clamped to [0, 1]. The default 1.0 means no change.
Values > 1.0 produce darker darks and lighter highlights.
Usage
image_apply_contrast(image, contrast = 1)
Arguments
image |
An image list returned by |
contrast |
Contrast multiplier. Default 1.0 (no change). Typical values: 1.1–1.2 for subtle S-curve, 1.5 for strong. |
Value
A new image list with contrast-adjusted pixel data.
Examples
cube <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(cube$vertices, cube$triangles)
img <- image_apply_contrast(img, contrast = 1.1)
Crop an image to a rectangular region
Description
Crop an image to a rectangular region
Usage
image_crop(image, x, y, w, h)
Arguments
image |
An image list returned by |
x |
Left edge of the crop region (0-based pixel coordinate). |
y |
Top edge of the crop region (0-based pixel coordinate). |
w |
Crop width in pixels. |
h |
Crop height in pixels. |
Value
A new image list with the cropped dimensions.
Examples
cube <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(cube$vertices, cube$triangles)
img <- image_crop(img, 100, 50, 400, 300)
Crop an image to its content bounding box
Description
Removes background-coloured margin from the specified edges of the image. The first non-background pixel found on each edge defines the crop boundary.
Usage
image_crop_to_content(image, direction, background)
Arguments
image |
An image list. |
direction |
One of |
background |
Numeric vector of length 4 with RGBA values in
|
Value
A new image list with cropped dimensions.
Examples
cube <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(cube$vertices, cube$triangles,
options = render_options(background_color = c(0, 0, 0, 0)))
img <- image_crop_to_content(img, "all", c(0, 0, 0, 0))
Grow an image by adding padding
Description
Expands the canvas by adding pixel rows/columns filled with a background colour.
Usage
image_grow(image, top, bottom, left, right, background)
Arguments
image |
An image list. |
top |
Number of pixel rows to add above. |
bottom |
Number of pixel rows to add below. |
left |
Number of pixel columns to add to the left. |
right |
Number of pixel columns to add to the right. |
background |
Numeric vector of length 4 with RGBA values in
|
Value
A new image list with the expanded dimensions.
Examples
cube <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(cube$vertices, cube$triangles)
img <- image_grow(img, 10, 10, 20, 20, c(1, 1, 1, 1))
Merge two images side by side or stacked
Description
Merges another image into this one at the specified edge. For left/right merging, the heights must match. For top/bottom, the widths must match.
Usage
image_merge(image, other, direction)
Arguments
image |
An image list. |
other |
Another image list. |
direction |
One of |
Value
A new image list with the merged dimensions.
Examples
cube <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
sphere <- generate_sphere(c(0, 0, 0), radius = 0.5)
left <- render_mesh(sphere$vertices, sphere$triangles)
right <- render_mesh(cube$vertices, cube$triangles)
merged <- image_merge(left, right, "right")
Rotate an image by 90 degrees
Description
Rotate an image by 90 degrees
Usage
image_rotate_90(image, clockwise = TRUE)
Arguments
image |
An image list. |
clockwise |
Logical, if |
Value
A new image list with width and height swapped.
Scale an image (nearest-neighbour)
Description
Resizes the image to the given dimensions using nearest-neighbour interpolation.
Usage
image_scale(image, new_width, new_height)
Arguments
image |
An image list. |
new_width |
Target width in pixels. |
new_height |
Target height in pixels. |
Value
A new image list with the new dimensions.
Convert a rendered image to an RGBA array
Description
Converts the output of render_mesh() or render_scene()
into a 3-dimensional R array of dimensions (height x width x 4) with
RGBA channels.
Usage
image_to_array(image)
Arguments
image |
An image list returned by |
Value
A 3D array of dimensions (height, width, 4) with values in
[0, 1].
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(mesh$vertices, mesh$triangles)
arr <- image_to_array(img)
dim(arr) # height x width x 4
Compute the axis-aligned bounding box of a mesh
Description
Compute the axis-aligned bounding box of a mesh
Usage
mesh_bbox(mesh)
Arguments
mesh |
A mesh descriptor list with |
Value
A list with min and max (each length-3 numeric).
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 2, 3))
bb <- mesh_bbox(mesh)
bb$min
bb$max
Convert an rgl tmesh3d to scimesh mesh format
Description
Extracts vertices and triangle indices from an rgl
tmesh3d object into the format expected by
render_mesh(). Does not require the rgl
package – any list with components vb (4xN
homogeneous coordinates) and it (3xM index matrix)
works.
Usage
mesh_from_rgl(tmesh)
Arguments
tmesh |
A list with components |
Value
A mesh descriptor list with vertices (Nx3)
and triangles (Mx3, 1-based indices).
Examples
fake <- list(vb = rbind(0:3, 0:3, 0:3, rep(1, 4)),
it = matrix(1:6, nrow = 3))
m <- mesh_from_rgl(fake)
m$vertices
m$triangles
Convert a scimesh mesh to rgl tmesh3d format
Description
Builds an rgl-compatible triangular mesh from a scimesh mesh
descriptor so that the result can be used with
rgl::shade3d() or other rgl functions.
Usage
mesh_to_rgl(mesh, color = NULL, face_color = NULL)
Arguments
mesh |
A scimesh mesh descriptor list with |
color |
Optional per-vertex colour, either a single length-4 RGBA vector (applied to all vertices) or an Nx4 matrix. |
face_color |
Optional per-face colour (Mx4 matrix). |
Value
A list with components vb (4xN homogeneous
coordinates), it (3xM 1-based index matrix), and
optionally normals and mat (material), suitable
for use with rgl's tmesh3d() and shade3d().
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
rgl_mesh <- mesh_to_rgl(mesh)
str(rgl_mesh)
Read a Wavefront OBJ file
Description
Reads a Wavefront OBJ file (with optional UV coordinates and normals)
and returns a scimesh mesh descriptor list with vertices,
triangles, and optionally uv and normals.
Usage
read_obj(path)
Arguments
path |
Path to the OBJ file. |
Value
A mesh descriptor list.
Examples
## Not run:
mesh <- read_obj("model.obj")
nrow(mesh$vertices)
## End(Not run)
Read a Stanford PLY file
Description
Reads a PLY file (ASCII or binary) with optional per-vertex colors
and returns a scimesh mesh descriptor list with vertices,
triangles, and optionally colors.
Usage
read_ply(path)
Arguments
path |
Path to the PLY file. |
Value
A mesh descriptor list.
Examples
## Not run:
mesh <- read_ply("model.ply")
nrow(mesh$vertices)
## End(Not run)
Read an STL file
Description
Reads an ASCII or binary STL file and returns a scimesh mesh
descriptor list with vertices, triangles, and
normals.
Usage
read_stl(path)
Arguments
path |
Path to the STL file. |
Value
A mesh descriptor list.
Examples
## Not run:
mesh <- read_stl("model.stl")
nrow(mesh$vertices)
## End(Not run)
Render line segments as thin cylinders
Description
Generates a merged cylinder mesh from start/end point pairs, radii, and colors, then renders it.
Usage
render_lines(
from,
to,
radii = 0.1,
colors,
camera,
options = render_options(),
segments = 12L
)
Arguments
from |
Nx3 numeric matrix of segment start points. |
to |
Nx3 numeric matrix of segment end points. |
radii |
Numeric vector of cylinder radii (length N, or 1 recycled to N). |
colors |
Nx4 numeric matrix of RGBA colours, or a single colour recycled to N. |
camera |
A camera list. |
options |
Render options. |
segments |
Number of sides around the cylinder (default 12). |
Value
An image list.
Examples
from <- matrix(c(0, 0, 0, 1, 1, 1), ncol = 3, byrow = TRUE)
to <- matrix(c(3, 0, 0, 0, 3, 0), ncol = 3, byrow = TRUE)
img <- render_lines(from, to, radii = 0.05,
colors = c(0, 0, 1, 1),
camera = camera_auto(rbind(from, to)))
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
Render a 3D mesh to an image
Description
Renders a single mesh using the scimesh software renderer.
The mesh can be specified either as separate
vertices/triangles matrices, as a scimesh mesh
descriptor list, or as an rgl tmesh3d-style list (with
vb/it components). rgl meshes are transparently
converted via mesh_from_rgl().
Usage
render_mesh(
vertices,
triangles = NULL,
colors = NULL,
face_colors = NULL,
normals = NULL,
uv = NULL,
texture = NULL,
camera = NULL,
options = render_options()
)
Arguments
vertices |
Either an Nx3 numeric matrix of vertex positions,
or a scimesh mesh descriptor list (with |
triangles |
Mx3 integer matrix of triangle indices (1-based).
Ignored when |
colors |
Optional Nx4 numeric matrix of RGBA vertex colors (0-1).
Use |
face_colors |
Optional Mx4 numeric matrix of per-face RGBA colors,
one row per triangle. When present, all three vertices of a triangle
use the same colour. Takes precedence over vertex |
normals |
Optional Nx3 numeric matrix of vertex normals. |
uv |
Optional Nx2 numeric matrix of texture coordinates (0-1). |
texture |
Optional texture image as a 3D array (H x W x 3 or 4)
with values in |
camera |
A camera list from |
options |
A render options list from |
Value
A list with components width, height, and
pixels (raw vector of RGBA values).
Examples
# Render a simple colored triangle
verts <- matrix(c(0, 0, 0, 1, 0, 0, 0.5, 1, 0), ncol = 3, byrow = TRUE)
tris <- matrix(1L, nrow = 1, ncol = 3)
cols <- matrix(c(1, 0, 0, 1, 0, 1, 0, 1, 0, 0, 1, 1), ncol = 4, byrow = TRUE)
img <- render_mesh(verts, tris, colors = cols)
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
# Render from a mesh descriptor list (scimesh format)
mesh_desc <- list(vertices = verts, triangles = tris, colors = cols)
img <- render_mesh(mesh_desc)
Create render options
Description
Create render options
Usage
render_options(
width = 800L,
height = 600L,
shading = c("smooth", "flat"),
backface_culling = TRUE,
background_color = c(0, 0, 0, 0),
default_color = c(0.7, 0.7, 0.7, 1),
invert_normals = FALSE,
wireframe = FALSE,
wireframe_color = c(0, 0, 0, 1),
projection = c("perspective", "orthographic"),
specular_color = c(0, 0, 0, 0),
shininess = 0,
lights = NULL,
ambient = 0.3,
contrast = 1,
fog_enabled = FALSE,
fog_start = 0,
fog_end = 1,
fog_color = c(0, 0, 0, 0),
threads = 0L,
clip_planes = NULL,
ssao_enabled = FALSE,
ssao_radius = 16,
ssao_intensity = 0.8,
aa_samples = 1L
)
Arguments
width |
Output image width in pixels. |
height |
Output image height in pixels. |
shading |
Shading mode: |
backface_culling |
Whether to cull back-facing triangles. |
background_color |
Background RGBA color as numeric vector of length 4 (values 0-1). |
default_color |
Default vertex color when no colors are provided. |
invert_normals |
Whether to invert surface normals. |
wireframe |
Whether to render in wireframe mode. |
wireframe_color |
RGBA color for wireframe edges (0-1
scale). Default |
projection |
Projection type: |
specular_color |
Specular highlight color (0-1 scale). When
|
shininess |
Specular exponent controlling highlight sharpness.
Higher values produce a tighter spot. Typical values: 32 (soft
plastic), 64 (shiny), 128 (glass). Default |
lights |
A list of light descriptors, each a list with
|
ambient |
Ambient light contribution (0-1). Default 0.3. |
contrast |
Contrast adjustment applied after shading, before
uint8_t conversion. Default 1.0 (no change). Values > 1.0 produce
darker darks and lighter highlights (S-curve). Formula:
|
fog_enabled |
Enable depth cueing (fog). Default |
fog_start |
Z-depth where fog begins (0 = near plane, 1 = far plane). Default 0. |
fog_end |
Z-depth where fog is fully opaque. Default 1. |
fog_color |
RGBA fog colour (0-1 scale). Defaults to
|
threads |
Number of render threads. 0 = auto-detect (use all cores), 1 = single-threaded (deterministic). Default 0. Requires OpenMP at compile time. |
clip_planes |
A list of clip plane descriptors, each a list
with |
ssao_enabled |
Enable screen-space ambient occlusion.
Default |
ssao_radius |
Screen-space sample radius in pixels. Default 16. |
ssao_intensity |
Occlusion strength (0-1). Default 0.8. |
aa_samples |
Anti-aliasing supersampling factor. Renders
internally at |
Value
A render options list for use with render_mesh() or
render_scene().
Examples
# Default options
opts <- render_options()
# High-resolution with anti-aliasing and specular highlights
opts <- render_options(width = 1200, height = 900,
aa_samples = 2L,
specular_color = c(0.4, 0.4, 0.4, 1),
shininess = 64)
# Wireframe with transparent background
opts <- render_options(wireframe = TRUE,
wireframe_color = c(0, 0, 0, 1),
background_color = c(0, 0, 0, 0))
Render screen-space point primitives
Description
Renders points as fixed-size filled circles in screen space with
depth testing. Unlike render_spheres(), point size is
measured in pixels and does not change with camera distance.
Usage
render_points(
positions,
colors,
radius = 3,
camera = camera_auto(positions),
options = render_options()
)
Arguments
positions |
Nx3 numeric matrix of point positions. |
colors |
Nx4 numeric matrix of RGBA colours (0-1 scale). |
radius |
Point radius in pixels. |
camera |
A camera list. |
options |
Render options. |
Value
An image list.
Examples
pts <- matrix(c(0, 1, 2, 0, 1, 2, 0, 0, 0),
ncol = 3)
colors = matrix(c(0, 1, 0, 1, 1, 0, 0, 1, 0, 0, 1, 1), ncol = 4)
img <- render_points(pts, colors = colors, radius = 5)
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
Render multiple meshes to an image
Description
Renders a list of meshes as a single scene using the scimesh
software renderer. Each element can be a scimesh mesh descriptor
or an rgl-style mesh (with vb/it); rgl meshes are
transparently converted.
Usage
render_scene(meshes, camera, options = render_options())
Arguments
meshes |
A list of mesh descriptors. Each element is a list
with components |
camera |
A camera list from |
options |
A render options list from |
Value
A list with components width, height, and
pixels (raw vector of RGBA values).
Examples
# Render two cubes side by side
cube1 <- generate_cuboid(c(-1.5, 0, 0), c(0.8, 0.8, 0.8), c(1, 0, 0, 1))
cube2 <- generate_cuboid(c( 1.5, 0, 0), c(0.8, 0.8, 0.8), c(0, 0, 1, 1))
cam <- camera_auto(list(cube1, cube2), direction = c(1, 1, 1))
img <- render_scene(list(cube1, cube2), cam,
render_options(width = 800, height = 600, background_color = c(1, 1, 1, 1)))
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
# Render multiple meshes together
scimesh_cube <- generate_cuboid(c(-1, 0, 0), c(0.5, 0.5, 0.5))
sphere <- generate_sphere(c(1, 0, 0), radius = 0.5, color = c(0, 1, 0, 1))
cam <- camera_auto(list(scimesh_cube, sphere), direction = c(1, 1, 1))
img <- render_scene(list(scimesh_cube, sphere), cam,
render_options(width = 400, height = 300, background_color = c(1, 1, 1, 1)))
Render multiple spheres from point data
Description
Generates a merged sphere mesh from a set of center points, radii, and colors, then renders it with the given camera and options.
Usage
render_spheres(
centers,
radii,
colors,
camera,
options = render_options(),
segments = 16L
)
Arguments
centers |
Nx3 numeric matrix of sphere centre coordinates. |
radii |
Numeric vector of sphere radii (length N, or 1 recycled to N). |
colors |
Nx4 numeric matrix of RGBA colours (0-1 scale), or a single colour recycled to N. |
camera |
A camera list from |
options |
Render options from |
segments |
Number of latitude/longitude segments per sphere (default 16). |
Value
An image list with width, height,
pixels.
Examples
centers <- matrix(c(0, 2, 4, 0, 0, 0, 0, 0, 0), ncol = 3)
img <- render_spheres(centers, radii = 0.5,
colors = c(1, 0, 0, 1),
camera = camera_auto(centers))
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
Render raw triangles without index buffer
Description
Renders triangle geometry where positions and colours are given as flat arrays with 3 vertices per triangle (no index buffer). Useful for voxel renderings, misc3d isosurfaces, and other dynamically generated geometry.
Usage
render_triangles(positions, colors, camera, options = render_options())
Arguments
positions |
Nx3 numeric matrix of vertex positions, where N is a multiple of 3 (3 per triangle). |
colors |
Nx4 numeric matrix of RGBA colours (0-1 scale). |
camera |
A camera list from |
options |
Render options from |
Value
An image list with width, height,
pixels.
Examples
# Render a single red triangle from raw vertices
positions <- matrix(c(0, 0, 0, 1, 0, 0, 0.5, 1, 0), ncol = 3, byrow = TRUE)
colors <- matrix(c(1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1), ncol = 4, byrow = TRUE)
cam <- camera_auto(positions)
img <- render_triangles(positions, colors, cam)
Rotate a mesh around an axis
Description
Rotate a mesh around an axis
Usage
rotate_mesh(mesh, angle_rad, axis = c(0, 0, 1))
Arguments
mesh |
A mesh descriptor list. |
angle_rad |
Rotation angle in radians. |
axis |
Length-3 numeric vector defining the rotation axis. |
Value
A new mesh descriptor list with rotated vertices.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
rotated <- rotate_mesh(mesh, pi / 4, axis = c(0, 1, 0))
rotated$vertices[1, ]
Scale a mesh uniformly or per-axis
Description
Scale a mesh uniformly or per-axis
Usage
scale_mesh(mesh, scale)
Arguments
mesh |
A mesh descriptor list. |
scale |
A single numeric scale factor (uniform) or a length-3 numeric vector for per-axis scaling (x, y, z). |
Value
A new mesh descriptor list with scaled vertices.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
big <- scale_mesh(mesh, 3)
flat <- scale_mesh(mesh, c(2, 0.5, 1))
Stack images horizontally
Description
Stacks a list of rendered images side by side. A convenience
wrapper around compose_layout().
Usage
stack_horizontal(
...,
colorbar = NULL,
colorbar_height = 80L,
colorbar_width = 80L,
background = c(0, 0, 0, 0),
colorbar_side = c("right", "left"),
crop = FALSE
)
Arguments
... |
Images from |
colorbar |
Optional colorbar. |
colorbar_height |
Height of the colorbar in pixels. |
colorbar_width |
Width of the colorbar in pixels. |
background |
Background RGBA color for padding. |
colorbar_side |
Side for the colorbar: |
crop |
If |
Value
A composed image list.
Examples
mesh1 <- generate_cuboid(c(-2, 0, 0), c(0.5, 1, 1), c(1, 0, 0, 1))
mesh2 <- generate_cuboid(c( 2, 0, 0), c(0.5, 1, 1), c(0, 0, 1, 1))
img1 <- render_mesh(mesh1$vertices, mesh1$triangles)
img2 <- render_mesh(mesh2$vertices, mesh2$triangles)
result <- stack_horizontal(img1, img2)
tmp_file <- tempfile(fileext = ".png")
write_png(result, tmp_file)
Stack images vertically
Description
Stacks a list of rendered images vertically (one below another).
A convenience wrapper around compose_layout().
Usage
stack_vertical(
...,
colorbar = NULL,
colorbar_height = 80L,
colorbar_width = 80L,
background = c(0, 0, 0, 0),
colorbar_side = c("right", "left"),
crop = FALSE
)
Arguments
... |
Images from |
colorbar |
Optional colorbar from |
colorbar_height |
Height of the colorbar in pixels. |
colorbar_width |
Width of the colorbar in pixels. |
background |
Background RGBA color for padding. |
colorbar_side |
Side for the colorbar: |
crop |
If |
Value
A composed image list.
Examples
mesh1 <- generate_cuboid(c(0, 2, 0), c(1, 0.5, 1), c(1, 0, 0, 1))
mesh2 <- generate_cuboid(c(0, -2, 0), c(1, 0.5, 1), c(0, 1, 0, 1))
img1 <- render_mesh(mesh1$vertices, mesh1$triangles)
img2 <- render_mesh(mesh2$vertices, mesh2$triangles)
result <- stack_vertical(img1, img2)
tmp_file <- tempfile(fileext = ".png")
write_png(result, tmp_file)
Apply a 4x4 transformation matrix to a mesh
Description
Transforms all vertex positions in a mesh by a 4x4 homogeneous
matrix (applied as M * (x, y, z, 1)^T). Vertex colors and
normals are untouched.
Usage
transform_mesh(mesh, matrix)
Arguments
mesh |
A mesh descriptor list with |
matrix |
A 4x4 numeric matrix. |
Value
A new mesh descriptor list with transformed vertices.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
mat <- diag(4)
mat[1:3, 4] <- c(2, 3, 4)
translated <- transform_mesh(mesh, mat)
translated$vertices[1, ]
Translate a mesh
Description
Translate a mesh
Usage
translate_mesh(mesh, translation)
Arguments
mesh |
A mesh descriptor list. |
translation |
Length-3 numeric vector (x, y, z). |
Value
A new mesh descriptor list with translated vertices.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
moved <- translate_mesh(mesh, c(5, 0, 0))
colMeans(moved$vertices)
Viridis colormap
Description
Returns the viridis color palette. A convenience wrapper around
grDevices::hcl.colors that mimics the viridis color scheme
without requiring extra packages.
Usage
viridis_colormap(n, alpha = 1, direction = 1)
Arguments
n |
Number of colors. |
alpha |
Alpha channel value (0-1). |
direction |
Forward (1) or reversed (-1) direction. |
Value
A character vector of hex color strings.
Examples
cols <- viridis_colormap(10)
plot(1:10, pch = 19, col = cols, cex = 3)
Write a rendered image to a PNG file
Description
Writes the output of render_mesh() or render_scene()
to a PNG file using the built-in C++ PNG writer (stb_image_write).
No additional R packages are required.
Usage
write_png(image, filename)
Arguments
image |
An image list returned by |
filename |
Output PNG file path. |
Value
No return value; called for side effects.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
img <- render_mesh(mesh$vertices, mesh$triangles)
tmp_file <- tempfile(fileext = ".png")
write_png(img, tmp_file)
Write a mesh to an STL file
Description
Writes a scimesh mesh descriptor to an ASCII or binary STL file.
Usage
write_stl(mesh, path, format = c("binary", "ascii"))
Arguments
mesh |
A mesh descriptor list. |
path |
Path to the output STL file. |
format |
|
Value
invisible NULL, called for side effects of writing the file.
Examples
mesh <- generate_cuboid(c(0, 0, 0), c(1, 1, 1))
tmp_file <- tempfile(fileext = ".stl")
write_stl(mesh, tmp_file, format = "binary")