Module mola.utils_color
Expand source code
#!/usr/bin/env python
# -*- coding: utf-8 -*-
__author__ = ['Benjamin Dillenburger','Demetris Shammas','Mathias Bernhard']
__copyright__ = 'Copyright 2019 / Digital Building Technologies DBT / ETH Zurich'
__license__ = 'MIT License'
__email__ = ['<dbt@arch.ethz.ch>']
import colorsys
from mola import utils_face
from mola import utils_math
from math import floor
def color_hue_to_rgb(hue, do_grayscale):
"""
Converts a color defined as Hue (HSV, saturation and value assumed to be 100%) into red, green and blue
and returns (r,g,b,1)
"""
if do_grayscale:
return (hue, hue, hue, 1)
else:
hue = utils_math.math_map(hue, 0.0, 1.0, 0.0, 0.8) #limit hue red-red to red-magenta
col = colorsys.hsv_to_rgb(hue, 1, 1)
return (col[0], col[1], col[2], 1) # alpha = 100 %
def color_faces_by_function(faces, faceFunction, do_grayscale=False):
"""
Assigns a color to all the faces by face-function which has to return a float value for a face as argument,
from smallest (red) to biggest (purple).
Arguments:
----------
faces: list of faces to color
faceFunction : one of the functions `ByCurvature`, `ByArea`, etc.
----------
Optional Arguments:
----------
do_grayscale: Boolean
"""
values = []
for face in faces:
values.append(faceFunction(face))
valueMin = min(values)
valueMax = max(values)
for i, face in enumerate(faces):
h = utils_math.math_map(values[i],valueMin, valueMax, 0.0, 1.0)
face.color = color_hue_to_rgb(h, do_grayscale)
def color_map(values=[], colors=[(1,0,0.5),(0,0.5,1)]):
"""
Maps a value to a color on a custom spectrum.
The values will be remapped from 0 to 1, the first color will be at 0, the
last at 1 and all other colors evenly spread between.
Arguments:
----------
values : list of floats
the list of values to be mapped
colors : list of (r,g,b) tuples
the colors along the spectrum
"""
value_min = min(values)
value_max = max(values)
values_mapped = [utils_math.math_map(v, value_min, value_max, 0.0, 0.999) for v in values]
interval = 1.0 / (len(colors) - 1)
output_colors = []
for v in values_mapped:
lower_ix = int(floor(v * (len(colors)-1)))
upper_ix = lower_ix + 1
rv = (v - (lower_ix * interval)) / interval
r = (1 - rv) * colors[lower_ix][0] + rv * colors[upper_ix][0]
g = (1 - rv) * colors[lower_ix][1] + rv * colors[upper_ix][1]
b = (1 - rv) * colors[lower_ix][2] + rv * colors[upper_ix][2]
output_colors.append((r,g,b,1))
return output_colors
def color_faces_by_map(faces, colors):
if len(faces) > len(colors):
print('not enough colors for all the faces')
return
for f,c in zip(faces, colors):
f.color = c
def _color_faces_by_list_and_scheme(faces, values=[], scheme=[(1,0,0.5),(0,0.5,1)]):
"""
Assigns a color to all the faces by a list of values and a list of colors.
The values will be remapped from 0 to 1, the first color will be at 0, the
last at 1 and all other colors evenly spread between.
Arguments:
----------
faces : mola.core.Face
list of faces to color
values : list of floats
one property value for each face
scheme : list of (r,g,b) tuples
the colors along the spectrum
"""
if len(faces) > len(values):
print('not enough values provided')
return
if len(scheme)<2:
print('at least two colors need to be provided')
#values = [face_function(f) for f in faces]
value_min = min(values)
value_max = max(values)
values_mapped = [utils_math.math_map(v, value_min, value_max, 0.0, 0.999) for v in values]
interval = 1.0 / (len(scheme) - 1)
for i,f in enumerate(faces):
v = values_mapped[i]
lower_ix = int(floor(v * (len(scheme)-1)))
upper_ix = lower_ix + 1
rv = (v - (lower_ix * interval)) / interval
r = (1 - rv) * scheme[lower_ix][0] + rv * scheme[upper_ix][0]
g = (1 - rv) * scheme[lower_ix][1] + rv * scheme[upper_ix][1]
b = (1 - rv) * scheme[lower_ix][2] + rv * scheme[upper_ix][2]
f.color = (r,g,b,1)
def color_faces_by_curvature(faces):
"""
Assigns a color to all the faces by curvature (require topological meshinformation),
from smallest (red) to biggest (purple).
"""
color_faces_by_function(faces, utils_face.face_curvature)
def color_faces_by_area(faces):
"""
Assigns a color to all the faces by area,
from smallest (red) to biggest (purple).
"""
color_faces_by_function(faces, utils_face.face_area)
def color_faces_by_perimeter(faces):
"""
Assigns a color to all the faces by perimeter,
from smallest (red) to biggest (purple).
"""
color_faces_by_function(faces, utils_face.face_perimeter)
def color_faces_by_compactness(faces):
"""
Assigns a color to all the faces by compactness (area/perimeter),
from smallest (red) to biggest (purple).
"""
color_faces_by_function(faces, utils_face.face_compactness)
def color_faces_by_horizontal_angle(faces):
color_faces_by_function(faces, utils_face.face_angle_horizontal)
def color_faces_by_vertical_angle(faces):
"""
Assigns a color to all the faces by verticality,
from smallest (red) to biggest (purple).
"""
color_faces_by_function(faces, utils_face.face_angle_vertical)
Functions
def color_faces_by_area(faces)
-
Assigns a color to all the faces by area, from smallest (red) to biggest (purple).
Expand source code
def color_faces_by_area(faces): """ Assigns a color to all the faces by area, from smallest (red) to biggest (purple). """ color_faces_by_function(faces, utils_face.face_area)
def color_faces_by_compactness(faces)
-
Assigns a color to all the faces by compactness (area/perimeter), from smallest (red) to biggest (purple).
Expand source code
def color_faces_by_compactness(faces): """ Assigns a color to all the faces by compactness (area/perimeter), from smallest (red) to biggest (purple). """ color_faces_by_function(faces, utils_face.face_compactness)
def color_faces_by_curvature(faces)
-
Assigns a color to all the faces by curvature (require topological meshinformation), from smallest (red) to biggest (purple).
Expand source code
def color_faces_by_curvature(faces): """ Assigns a color to all the faces by curvature (require topological meshinformation), from smallest (red) to biggest (purple). """ color_faces_by_function(faces, utils_face.face_curvature)
def color_faces_by_function(faces, faceFunction, do_grayscale=False)
-
Assigns a color to all the faces by face-function which has to return a float value for a face as argument, from smallest (red) to biggest (purple).
Arguments:
faces: list of faces to color faceFunction : one of the functions
ByCurvature
,ByArea
, etc.
Optional Arguments:
do_grayscale: Boolean
Expand source code
def color_faces_by_function(faces, faceFunction, do_grayscale=False): """ Assigns a color to all the faces by face-function which has to return a float value for a face as argument, from smallest (red) to biggest (purple). Arguments: ---------- faces: list of faces to color faceFunction : one of the functions `ByCurvature`, `ByArea`, etc. ---------- Optional Arguments: ---------- do_grayscale: Boolean """ values = [] for face in faces: values.append(faceFunction(face)) valueMin = min(values) valueMax = max(values) for i, face in enumerate(faces): h = utils_math.math_map(values[i],valueMin, valueMax, 0.0, 1.0) face.color = color_hue_to_rgb(h, do_grayscale)
def color_faces_by_horizontal_angle(faces)
-
Expand source code
def color_faces_by_horizontal_angle(faces): color_faces_by_function(faces, utils_face.face_angle_horizontal)
def color_faces_by_map(faces, colors)
-
Expand source code
def color_faces_by_map(faces, colors): if len(faces) > len(colors): print('not enough colors for all the faces') return for f,c in zip(faces, colors): f.color = c
def color_faces_by_perimeter(faces)
-
Assigns a color to all the faces by perimeter, from smallest (red) to biggest (purple).
Expand source code
def color_faces_by_perimeter(faces): """ Assigns a color to all the faces by perimeter, from smallest (red) to biggest (purple). """ color_faces_by_function(faces, utils_face.face_perimeter)
def color_faces_by_vertical_angle(faces)
-
Assigns a color to all the faces by verticality, from smallest (red) to biggest (purple).
Expand source code
def color_faces_by_vertical_angle(faces): """ Assigns a color to all the faces by verticality, from smallest (red) to biggest (purple). """ color_faces_by_function(faces, utils_face.face_angle_vertical)
def color_hue_to_rgb(hue, do_grayscale)
-
Converts a color defined as Hue (HSV, saturation and value assumed to be 100%) into red, green and blue and returns (r,g,b,1)
Expand source code
def color_hue_to_rgb(hue, do_grayscale): """ Converts a color defined as Hue (HSV, saturation and value assumed to be 100%) into red, green and blue and returns (r,g,b,1) """ if do_grayscale: return (hue, hue, hue, 1) else: hue = utils_math.math_map(hue, 0.0, 1.0, 0.0, 0.8) #limit hue red-red to red-magenta col = colorsys.hsv_to_rgb(hue, 1, 1) return (col[0], col[1], col[2], 1) # alpha = 100 %
def color_map(values=[], colors=[(1, 0, 0.5), (0, 0.5, 1)])
-
Maps a value to a color on a custom spectrum. The values will be remapped from 0 to 1, the first color will be at 0, the last at 1 and all other colors evenly spread between.
Arguments:
values : list of floats the list of values to be mapped colors : list of (r,g,b) tuples the colors along the spectrum
Expand source code
def color_map(values=[], colors=[(1,0,0.5),(0,0.5,1)]): """ Maps a value to a color on a custom spectrum. The values will be remapped from 0 to 1, the first color will be at 0, the last at 1 and all other colors evenly spread between. Arguments: ---------- values : list of floats the list of values to be mapped colors : list of (r,g,b) tuples the colors along the spectrum """ value_min = min(values) value_max = max(values) values_mapped = [utils_math.math_map(v, value_min, value_max, 0.0, 0.999) for v in values] interval = 1.0 / (len(colors) - 1) output_colors = [] for v in values_mapped: lower_ix = int(floor(v * (len(colors)-1))) upper_ix = lower_ix + 1 rv = (v - (lower_ix * interval)) / interval r = (1 - rv) * colors[lower_ix][0] + rv * colors[upper_ix][0] g = (1 - rv) * colors[lower_ix][1] + rv * colors[upper_ix][1] b = (1 - rv) * colors[lower_ix][2] + rv * colors[upper_ix][2] output_colors.append((r,g,b,1)) return output_colors