https://github.com/statnmap/mesh2ray
Transform mesh3d to ray* objects
https://github.com/statnmap/mesh2ray
Last synced: 2 months ago
JSON representation
Transform mesh3d to ray* objects
- Host: GitHub
- URL: https://github.com/statnmap/mesh2ray
- Owner: statnmap
- License: gpl-3.0
- Created: 2019-04-10T12:37:30.000Z (about 7 years ago)
- Default Branch: master
- Last Pushed: 2019-07-24T21:51:52.000Z (almost 7 years ago)
- Last Synced: 2025-03-17T15:59:30.379Z (over 1 year ago)
- Language: R
- Size: 1.18 MB
- Stars: 3
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.Rmd
- License: LICENSE.md
- Code of conduct: CODE_OF_CONDUCT.md
Awesome Lists containing this project
README
---
output: github_document
---
```{r setup, include = FALSE}
knitr::opts_chunk$set(
collapse = TRUE,
comment = "#>",
fig.path = "reference/figures/README-",
out.width = "100%"
)
```
[](https://travis-ci.org/statnmap/mesh2ray)
# mesh2ray
The goal of mesh2ray is to transform mesh3d to objects that can be used with ['rayshader'](https://github.com/tylermorganwall/rayshader) or ['rayrender'](https://github.com/tylermorganwall/rayrender).
The corresponding blog post is [Play with mesh3d, rayshader and rayrender](https://statnmap.com/2019-04-02-mesh3d-rayshader-and-rayrender/).
## Installation
You can install the released version of {mesh2ray} from Github
``` r
#install.packages("remotes")
remotes::install_github("statnmap/mesh2ray")
```
## Play with mesh3d and ray's
```{r example}
library(mesh2ray)
library(raster)
library(Rvcg)
library(magick)
extraWD <- "reference/figures"
```
## Transfrom mesh3d to raster and then {rayshader}
```{r rayshader, eval=FALSE}
# Create simple mesh
simple_mesh_orig <- Rvcg::vcgIcosahedron()
# 1. Cut it with a plane with {Morpho}
v1 <- c(0, 0, -0.5)
v2 <- c(1, 0, -0.5)
v3 <- c(0, 1, -0.5)
simple_mesh <- Morpho::cutMeshPlane(simple_mesh_orig, v1, v2, v3)
# _plot3d
plot3d(simple_mesh, col = "cyan")
aspect3d(1, 1, 0.2)
plot3d(simple_mesh, type = "wire", add = TRUE)
plot3d(t(simple_mesh$vb), type = "s", radius = 0.1, add = TRUE)
view3d(theta = 20, phi = -40, zoom = 0.5, fov = 80)
# _snapshot
rgl.snapshot(filename = file.path(extraWD, "rayshader-simple-1-mesh.png"))
rgl::rgl.close()
# 2. Project on raster
simple_r <- mesh2ray::mesh_to_raster(simple_mesh, res = 26)
png(filename = file.path(extraWD, "rayshader-simple-2-raster.png"))
plot(simple_r)
dev.off()
# 3. raster to matrix
simple_ray <- mesh2ray::stack_to_ray(simple_r)
# 4. Rayshade matrix
zscale <- 0.4
ambmat <- ambient_shade(simple_ray$elevation, zscale = zscale)
raymat <- ray_shade(simple_ray$elevation, zscale = zscale, lambert = TRUE,
sunangle = 300)
ray_image <- simple_ray$elevation %>%
sphere_shade(texture = "unicorn") %>%
add_shadow(raymat, max_darken = 0.1) %>%
add_shadow(ambmat, max_darken = 0.5)
# _plot 3d
ray_image %>%
plot_3d(simple_ray$elevation, zscale = zscale, windowsize = c(1000, 1000),
soliddepth = -max(simple_ray$elevation, na.rm = TRUE)/zscale,
theta = -30, phi = 50, zoom = 0.7, fov = 20
)
# _snapshot
rgl.snapshot(filename = file.path(extraWD, "rayshader-simple-3-ray3d.png"))
rgl::rgl.close()
```
```{r steprayshader, echo=FALSE}
# Image montage
img_frames <- list.files(extraWD, pattern = "rayshader-simple", full.names = TRUE)
image_append(image_scale(image_read(img_frames), "400"))
```
## Transfrom mesh3d to regular mesh then {rayrender}
```{r rayrender, eval=FALSE}
# Create simple mesh
simple_mesh <- Rvcg::vcgIcosahedron()
# _plot3d
plot3d(simple_mesh, col = "cyan")
aspect3d("iso")
plot3d(simple_mesh, type = "wire", add = TRUE)
plot3d(t(simple_mesh$vb), type = "s", radius = 0.1, add = TRUE)
view3d(theta = 0, phi = 10, zoom = 0.6, fov = 80)
# _snapshot
rgl.snapshot(filename = file.path(extraWD, "rayrender-simple-1-mesh.png"))
rgl::rgl.close()
# 1. Uniformely resample mesh
# _vcgUniformRemesh is included in mesh_to_cubes()
simple_resample <- vcgUniformRemesh(simple_mesh, voxelSize = 0.5, multiSample = TRUE,
discretize = TRUE)
plot3d(simple_resample, col = "cyan")
aspect3d("iso")
plot3d(simple_resample, type = "wire", add = TRUE)
plot3d(t(simple_resample$vb), type = "s", radius = 0.1, add = TRUE)
view3d(theta = 0, phi = 10, zoom = 0.6, fov = 80)
# _snapshot
rgl.snapshot(filename = file.path(extraWD, "rayrender-simple-2-regularmesh.png"))
rgl::rgl.close()
# 2. Calculate cube positions in a specific scene
# _vcgUniformRemesh is included in mesh_to_cubes()
simple_cubes <- mesh2ray::mesh_to_cubes(simple_mesh, voxelSize = 0.5, scene_dim = c(80, 475))
# 3. Draw with rayrender
# _scene
scene <- generate_cornell(lightintensity = 10)
# _add cubes on scene
scene <- mesh2ray::add_cubes_to_scene(scene, cubes = simple_cubes,
material = dielectric(color = "green"))
# _draw scene /!\ long calculation /!\
if (!file.exists(file.path(extraWD, "rayrender-simple-3-scene.png"))) {
options(cores = 4)
render_scene(scene, lookfrom = c(278, 278, -800) ,
lookat = c(278, 278, 0), fov = 40, ambient_light = FALSE,
samples = 500, parallel = TRUE, clamp_value = 5,
filename = file.path(extraWD, "rayrender-simple-3-scene.png"))
}
```
```{r steprayrender, echo=FALSE}
# Image montage
img_frames <- list.files(extraWD, pattern = "rayrender-simple", full.names = TRUE)
image_append(image_scale(image_read(img_frames), "400"))
```
This package comes with a {pkgdown} documentation: https://statnmap.github.io/mesh2ray/
Please note that the 'mesh2ray' project is released with a [Contributor Code of Conduct](CODE_OF_CONDUCT.md). By contributing to this project, you agree to abide by its terms.