Skip to content

Instantly share code, notes, and snippets.

@ryantimpe
Created September 1, 2020 20:23
Show Gist options
  • Save ryantimpe/f74a4df80165416337306432a0115c1d to your computer and use it in GitHub Desktop.
Save ryantimpe/f74a4df80165416337306432a0115c1d to your computer and use it in GitHub Desktop.
brickr::bricks_from_coords() with custom colors
#Only two big differences...
# Swap out brickr::lego_colors for lego_colors on line 57
# added brickr::: to collect_bricks() on line 89
bricks_from_coords_w_custom_colors <- function(coord_table,
use_bricks = NULL,
increment_level = 0, min_level = 1, max_level = Inf,
increment_x = 0, max_x = Inf,
increment_y = 0, max_y = Inf,
exclude_color = NULL, exclude_level = NULL){
#Reformat input table to consistent format
bricks_raw <- coord_table
#Check for x y z and Color columns
names(bricks_raw)[names(bricks_raw) %in% c("X", "Y", "Z")] <- tolower(names(bricks_raw)[names(bricks_raw) %in% c("X", "Y", "Z")])
names(bricks_raw)[tolower(names(bricks_raw)) == "color"] <- "Color"
if(!all(c("x", "y", "z", "Color") %in% names(bricks_raw))){
stop("Input 'coord_table' must include the columns x, y, z, and Color. z should be >1. Color uses offical brick color names. See build_colors().")
}
#Set mid_level = 0 if not in data
if(!("mid_level" %in% names(bricks_raw))){
bricks_raw <- bricks_raw %>%
dplyr::mutate(mid_level = 0)
}
if(!any(unique(bricks_raw$mid_level) %in% 0:2)){
stop("Column 'mid_level' must be equal to 0, 1, or 2. 0 is the default base level, 1 is the middle of the level, and 2 is the top of the level. Exclude column unless necessary.")
}
#x, y, z, must be whole numbers and unique
bricks_raw <- bricks_raw %>%
dplyr::mutate_at(dplyr::vars("x", "y", "z"), round) %>%
dplyr::group_by(x, y, z, mid_level) %>%
dplyr::filter(dplyr::row_number() == 1) %>%
dplyr::ungroup()
#Need to assume users might supply NA-supressed or non-cube data. But layer_from_brick() needs cubes.
bricks_full <- expand.grid(
x = min(bricks_raw$x):max(bricks_raw$x),
y = min(bricks_raw$y):max(bricks_raw$y),
z = min(bricks_raw$z):max(bricks_raw$z)
) %>%
dplyr::left_join(bricks_raw, by = c("x", "y", "z"))
#Clean up increments
incr_level <- as.numeric(increment_level)[1]
if(is.na(incr_level)){incr_level<-0}
incr_x <- as.numeric(increment_x)[1]
if(is.na(incr_x)){incr_x<-0}
incr_y <- as.numeric(increment_y)[1]
if(is.na(incr_y)){incr_y<-0}
brick_set <- bricks_full %>%
dplyr::rename(Level = z) %>%
dplyr::left_join(lego_colors %>% dplyr::select(Color, dplyr::contains("_lego")),
by = "Color") %>%
dplyr::mutate_at(dplyr::vars(dplyr::contains("_lego")), list(~ifelse(is.na(.), 0, .))) %>%
dplyr::mutate(Lego_color = grDevices::rgb(R_lego, G_lego, B_lego)) %>%
dplyr::mutate(Lego_color = ifelse(is.na(Color), NA, Lego_color)) %>%
dplyr::rename(Lego_name = Color) %>%
dplyr::arrange(Level) %>%
#Exclusions
dplyr::filter(!(Lego_name %in% exclude_color)) %>%
dplyr::filter(!(Level %in% exclude_level)) %>%
#Increment coordinates
dplyr::mutate(Level = Level + incr_level,
x = x + incr_x, y = y + incr_y) %>%
dplyr::filter(Level >= 1, Level <= max_level,
x >= 1, x <= max_x,
y >= 1, y <= max_y) %>%
#In the end, drop empty levels
dplyr::group_by(Level) %>%
dplyr::filter(!all(is.na(Lego_color))) %>%
dplyr::ungroup()
if(!("piece_type" %in% names(brick_set))){
brick_set <- brick_set %>%
dplyr::mutate(piece_type = "b")
}
#Return an object from collect_bricks()
return(
list(Img_lego = brick_set,
brickr_object = "3dmodel") %>% brickr:::collect_bricks(use_bricks = use_bricks)
)
}
library(brickr)
lego_colors <- brickr::lego_colors %>%
dplyr::bind_rows(
#Need these columns.
# Value of lum just decided the color of the brick outline...
# ...Set close to 1 for light, close to 0 for dark
tibble::tibble(Color = "Hot pink",
R_lego = 1, G_lego = 0, B_lego = 0.5, Trans_lego = FALSE,
lum = 0.8)
)
brick <- data.frame(
x = 1:4,
y = 1, z=1,
color = "Hot pink",
stringsAsFactors=FALSE)
brick %>%
bricks_from_coords_w_custom_colors() %>%
brickr::build_bricks()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment