diff --git a/.travis.yml b/.travis.yml index 5c20c69..edb2b2e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,7 +13,6 @@ addons: packages: - libgdal-dev - libproj-dev - - r-cran-rayshader #env env: diff --git a/NEWS.md b/NEWS.md index 6cff7fe..848da9d 100644 --- a/NEWS.md +++ b/NEWS.md @@ -8,6 +8,8 @@ * New shapes! Plates, cheese slopes, round 1x1 bricks, conical 1x1 bricks. +* Removed bricks_from_rayshader() and build_bricks_rayshader() to decrease the complexity of package. + ## ggplot Extension * Removed from brickr. Will be rewritten as its own package. diff --git a/R/bricks-from-mosaic.R b/R/bricks-from-mosaic.R index f848367..e70c5b7 100644 --- a/R/bricks-from-mosaic.R +++ b/R/bricks-from-mosaic.R @@ -3,7 +3,7 @@ #' @param mosaic_list List output from collect_bricks() or image_to_bricks(). Contains an element \code{Img_lego}. #' @param mosaic_height Number of layers in the 3D image. #' @param highest_el Brick height is determined by brightness of color. Use \code{highest_el = 'dark'} for darkest bricks to have \code{mosaic_height}. -#' @return A list with elements \code{threed_elevation} and \code{threed_hillshade} to created 3D mosiacs with the \code{rayshader} package. +#' @return A list with elements \code{Img_lego} to pass to \code{collect_bricks()}. #' @family 3D Models #' @export #' diff --git a/R_experiments/models-from-other.Rmd b/R_experiments/models-from-other.Rmd new file mode 100644 index 0000000..85cc558 --- /dev/null +++ b/R_experiments/models-from-other.Rmd @@ -0,0 +1,100 @@ +--- +title: "3D Models from mosaics & rayshader" +output: rmarkdown::html_vignette +vignette: > + %\VignetteIndexEntry{models-from-other} + %\VignetteEngine{knitr::rmarkdown} + %\VignetteEncoding{UTF-8} +--- + +```{r, include = FALSE} +knitr::opts_chunk$set( +collapse = TRUE, +comment = "#>" +) +rgl::setupKnitr() +``` + +```{r setup, include = FALSE} +library(brickr) +``` + +## Getting started + +The `bricks_from_*` series of functions creates 3D models of LEGO bricks from a variety of input formats. + +## 3D mosaics + +Begin with a brickr mosaic from an image. Rather than graphically rendering the mosaic using `build_mosaic()`, use `bricks_from_mosaic()`. This function takes two other inputs: + +* `mosaic_height` is the number of bricks stacked at the mosaic's highest point. The default is 6. +* `highest_el` specifies if 'light' or 'dark' color bricks should be the tallest in the model. The default is 'light'. + +```{r bricks_6, rgl=TRUE, dev='png', echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4} +demo_img = tempfile() +download.file("http://ryantimpe.com/files/mf_unicorn.PNG", demo_img, mode="wb") + +mosaic <- png::readPNG(demo_img) %>% + image_to_mosaic() + +mosaic %>% build_mosaic() +``` + +```{r bricks_6a, rgl=TRUE, dev='png', echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4} +mosaic %>% + bricks_from_mosaic(highest_el = "dark") %>% + build_bricks() + +#From dput(round(rgl::par3d("userMatrix"),1)) after manual rotation +custom_rotation <- structure(c(0.9, 0.3, -0.3, 0, -0.3, 0.9, -0.3, + 0, 0.2, 0.4, 0.9, 0, 0, 0, 0, 1), .Dim = c(4L, 4L)) + +rgl::par3d(userMatrix = rgl::rotate3d(custom_rotation, 0, 0, pi/4 ,1)) +``` + +## Models from rayshader + +[rayshader](https://www.rayshader.com/) by [Tyler Morgan-Wall](https://twitter.com/tylermorganwall) is an open source package for producing 2D and 3D data visualizations in R. rayshader uses elevation data in a base R matrix and a combination of raytracing, spherical texture mapping, overlays, and ambient occlusion to generate beautiful topographic 2D and 3D maps. (Note: text lifted straight from [rayshader.com](https://www.rayshader.com/).) + +3D models in **brickr** are rendered using the functions in **rayshader**. Using `bricks_from_rayshader()`, you can convert rayshader map output into a brickr model. This function takes three inputs: + +* `hillshade` is topographic image matrix with an RGB channel (much like the mosaics). +* `heightmap` is a two-dimensional matrix specifiying the height of the image at each location. +* `max_height` is the number of bricks stacked at the mosaic's highest point. The default is 12. +* `img_size` is the number of bricks on each side of the model. The default is 48. + +```{r bricks_rayshader, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4} +library(rayshader) + +#Example from rayshader.com + +#Here, I load a map with the raster package. +loadzip = tempfile() +download.file("https://tylermw.com/data/dem_01.tif.zip", loadzip) +localtif = raster::raster(unzip(loadzip, "dem_01.tif")) +unlink(loadzip) + +#And convert it to a matrix: +elmat = matrix(raster::extract(localtif, raster::extent(localtif), buffer = 1000), + nrow = ncol(localtif), ncol = nrow(localtif)) + +rayshader_object <- elmat %>% + sphere_shade(texture = "desert") %>% + add_water(detect_water(elmat), color = "desert") %>% + add_shadow(ray_shade(elmat, zscale = 3, maxsearch = 300), 0.5) + +#Plot with rayshader +rayshader_object %>% + plot_3d(elmat, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800)) + +rayshader::render_snapshot(clear = TRUE) + +#Plot as bricks +rayshader_object %>% + bricks_from_rayshader(elmat) %>% + build_bricks_rayshader(theta = 135, phi = 45) + +rayshader::render_snapshot(clear = TRUE) +``` + +This example is rendered using `build_bricks_rayshader()`, which a bit faster for very large sets. \ No newline at end of file diff --git a/vignettes/models-from-other.Rmd b/vignettes/models-from-other.Rmd index 85cc558..f181c09 100644 --- a/vignettes/models-from-other.Rmd +++ b/vignettes/models-from-other.Rmd @@ -1,5 +1,5 @@ --- -title: "3D Models from mosaics & rayshader" +title: "3D Models from mosaics" output: rmarkdown::html_vignette vignette: > %\VignetteIndexEntry{models-from-other} @@ -51,50 +51,3 @@ custom_rotation <- structure(c(0.9, 0.3, -0.3, 0, -0.3, 0.9, -0.3, rgl::par3d(userMatrix = rgl::rotate3d(custom_rotation, 0, 0, pi/4 ,1)) ``` - -## Models from rayshader - -[rayshader](https://www.rayshader.com/) by [Tyler Morgan-Wall](https://twitter.com/tylermorganwall) is an open source package for producing 2D and 3D data visualizations in R. rayshader uses elevation data in a base R matrix and a combination of raytracing, spherical texture mapping, overlays, and ambient occlusion to generate beautiful topographic 2D and 3D maps. (Note: text lifted straight from [rayshader.com](https://www.rayshader.com/).) - -3D models in **brickr** are rendered using the functions in **rayshader**. Using `bricks_from_rayshader()`, you can convert rayshader map output into a brickr model. This function takes three inputs: - -* `hillshade` is topographic image matrix with an RGB channel (much like the mosaics). -* `heightmap` is a two-dimensional matrix specifiying the height of the image at each location. -* `max_height` is the number of bricks stacked at the mosaic's highest point. The default is 12. -* `img_size` is the number of bricks on each side of the model. The default is 48. - -```{r bricks_rayshader, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4} -library(rayshader) - -#Example from rayshader.com - -#Here, I load a map with the raster package. -loadzip = tempfile() -download.file("https://tylermw.com/data/dem_01.tif.zip", loadzip) -localtif = raster::raster(unzip(loadzip, "dem_01.tif")) -unlink(loadzip) - -#And convert it to a matrix: -elmat = matrix(raster::extract(localtif, raster::extent(localtif), buffer = 1000), - nrow = ncol(localtif), ncol = nrow(localtif)) - -rayshader_object <- elmat %>% - sphere_shade(texture = "desert") %>% - add_water(detect_water(elmat), color = "desert") %>% - add_shadow(ray_shade(elmat, zscale = 3, maxsearch = 300), 0.5) - -#Plot with rayshader -rayshader_object %>% - plot_3d(elmat, zscale = 10, fov = 0, theta = 135, zoom = 0.75, phi = 45, windowsize = c(1000, 800)) - -rayshader::render_snapshot(clear = TRUE) - -#Plot as bricks -rayshader_object %>% - bricks_from_rayshader(elmat) %>% - build_bricks_rayshader(theta = 135, phi = 45) - -rayshader::render_snapshot(clear = TRUE) -``` - -This example is rendered using `build_bricks_rayshader()`, which a bit faster for very large sets. \ No newline at end of file diff --git a/vignettes/models-from-tables.Rmd b/vignettes/models-from-tables.Rmd index effa73b..288cae2 100644 --- a/vignettes/models-from-tables.Rmd +++ b/vignettes/models-from-tables.Rmd @@ -115,29 +115,6 @@ tree_or_mushroom %>% rgl::par3d(userMatrix = rgl::rotate3d(rgl::par3d("userMatrix"), 1.1*pi/4, 0, 0 ,1)) ``` -### Plates instead of bricks - -**Currently unavailable in `build_bricks()`. Use `build_bricks_rayshader()`** - -That's clearly a tree, right? Why is the data frame called 'tree_or_mushroom'? - -Use the input 'brick_type="plate"' to render the 3D model using LEGO plates rather than bricks, which are 1/3 as tall. - -```{r bricks_5a, echo=TRUE, warning=FALSE, message=FALSE, fig.width=4, fig.height=4} -brick_colors <- tibble::tribble( - ~`.value`, ~Color, - 1, "Dark green", - 2, "Light nougat", - 3, "Bright red" -) - -tree_or_mushroom %>% - bricks_from_table(brick_colors) %>% - build_bricks_rayshader(theta = 210, phi = 10, brick_res = "hd", brick_type="plate") - -rayshader::render_snapshot(clear = TRUE) -``` - ## Bricks from Excel When designing larger models, it is much easier to use a spreadsheet program to lay out the bricks for each level. diff --git a/vignettes/mosaics.Rmd b/vignettes/mosaics.Rmd index 212953f..0b170de 100644 --- a/vignettes/mosaics.Rmd +++ b/vignettes/mosaics.Rmd @@ -139,13 +139,13 @@ The input `brightness` can be used to scale up or down the RGB values of the ima ## 3D Mosaics -With [rayshader](https://www.rayshader.com/) installed, passing the mosaic object to `bricks_from_mosaic()` will render a 3D object, stacking layers of bricks on each other to create an elevated mosaic. By default, the lightest color bricks will be on top, but this can be changed using the `highest_el = 'dark'` option. +Passing the mosaic object to `bricks_from_mosaic()` will render a 3D object, stacking layers of bricks on each other to create an elevated mosaic. By default, the lightest color bricks will be on top, but this can be changed using the `highest_el = 'dark'` option. ```{r c_threed, rgl=TRUE, dev='png'} png::readPNG(demo_img) %>% image_to_mosaic(32) %>% bricks_from_mosaic(highest_el = "dark") %>% - build_bricks() + build_bricks(outline_bricks = TRUE, rgl_lit = FALSE) #From dput(round(rgl::par3d("userMatrix"),1)) after manual rotation custom_rotation <- structure(c(0.9, 0.3, -0.3, 0, -0.3, 0.9, -0.3,