-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
move color funcs from mesh to colors. move rasterize funcs into image.
- Loading branch information
Olaf Haag
committed
Dec 15, 2023
1 parent
bc86e8c
commit 1f62522
Showing
12 changed files
with
928 additions
and
935 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,3 @@ | ||
"""Module for drawing operations on images.""" | ||
from readyplayerme.meshops.draw.colormodes import * # noqa: F403 | ||
from readyplayerme.meshops.draw.color import * # noqa: F403 | ||
from readyplayerme.meshops.draw.image import * # noqa: F403 | ||
from readyplayerme.meshops.draw.rasterize import * # noqa: F403 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,114 @@ | ||
"""Functions to deal with colors and color modes.""" | ||
import numpy as np | ||
|
||
from readyplayerme.meshops.types import Color, ColorMode, Image, IndexGroups | ||
|
||
|
||
def get_image_color_mode(image: Image) -> ColorMode: | ||
""" | ||
Determine the color mode of an image. | ||
:param image: An image array. | ||
:return ColorMode:: Enum indicating the color mode of the image (GRAYSCALE, RGB, or RGBA). | ||
""" | ||
try: | ||
n_channels = image.shape[-1] | ||
except IndexError as error: | ||
error_msg = "Image has invalid shape: zero dimensions." | ||
raise ValueError(error_msg) from error | ||
match image.ndim, n_channels: | ||
case 2, _: | ||
return ColorMode.GRAYSCALE | ||
case 3, 3: | ||
return ColorMode.RGB | ||
case 3, 4: | ||
return ColorMode.RGBA | ||
case _: | ||
error_msg = "Invalid color mode for an image." | ||
raise ValueError(error_msg) | ||
|
||
|
||
def get_color_array_color_mode(color_array: Color) -> ColorMode: | ||
""" | ||
Determine the color mode of a color array. | ||
:param color_array: An array representing colors. | ||
:return ColorMode: Enum indicating the color mode of the color array (GRAYSCALE, RGB, or RGBA). | ||
""" | ||
try: | ||
n_channels = color_array.shape[-1] | ||
except IndexError as error: | ||
error_msg = "Color has invalid shape: zero dimensions." | ||
raise ValueError(error_msg) from error | ||
match color_array.ndim, n_channels: | ||
case 1, _: | ||
return ColorMode.GRAYSCALE | ||
case 2, 1: | ||
return ColorMode.GRAYSCALE | ||
case 2, 3: | ||
return ColorMode.RGB | ||
case 2, 4: | ||
return ColorMode.RGBA | ||
case _: | ||
msg = "Invalid dimensions for a color array." | ||
raise ValueError(msg) | ||
|
||
|
||
def blend_colors(colors: Color, index_groups: IndexGroups) -> Color: | ||
"""Blend colors according to the given grouped indices. | ||
Colors at indices in the same group are blended into having the same color. | ||
:param index_groups: Groups of indices. Indices must be within the bounds of the colors array. | ||
:param vertex_colors: Colors. | ||
:return: Colors with new blended colors at given indices. | ||
""" | ||
if not len(colors): | ||
return np.empty_like(colors) | ||
|
||
blended_colors = np.copy(colors) | ||
if not index_groups: | ||
return blended_colors | ||
|
||
# Check that the indices are within the bounds of the colors array, | ||
# so we don't start any operations that would later fail. | ||
try: | ||
colors[np.hstack(index_groups)] | ||
except IndexError as error: | ||
msg = f"Index in index groups is out of bounds for colors: {error}" | ||
raise IndexError(msg) from error | ||
|
||
# Blending process | ||
for group in index_groups: | ||
if len(group): # A mean-operation with an empty group would return nan values. | ||
blended_colors[group] = np.mean(colors[group], axis=0) | ||
|
||
return blended_colors | ||
|
||
|
||
def interpolate_values(start: Color, end: Color, num_steps: int) -> Color: | ||
""" | ||
Return an array with interpolated values between start and end. | ||
The array includes start and end values and is of length num_steps+2, with the first element being start, | ||
and the last being end, and in between elements are linearly interpolated between these values. | ||
:param start: The starting value(s) for interpolation.Ex. Colors (G, RGB, RGBA), Normals, etc.. | ||
:param end: The ending value(s) for interpolation.Ex. Colors (G, RGB, RGBA), Normals, etc.. | ||
:param num_steps: The number of interpolation steps. | ||
:return: An array of interpolated values. | ||
""" | ||
if start.shape != end.shape: | ||
msg = "Start and end values must have the same shape." | ||
raise ValueError(msg) | ||
|
||
if num_steps < 1: | ||
msg = "Number of steps must be at least 1." | ||
raise ValueError(msg) | ||
|
||
t = np.arange(num_steps) / max(num_steps - 1, 1) | ||
|
||
if start.size == 1 and start.ndim == 1: | ||
return start + t * (end - start) | ||
else: | ||
return start[None, :] + t[:, None] * (end - start) |
This file was deleted.
Oops, something went wrong.
Oops, something went wrong.