Working on a Python script, and I have a Random Color assigned to a new layer – but I’d like to be able to specify ranges of its HSV values (eg. Set a Pastel-type look with Saturation=15-25)
Thinking maybe I need to find a way to define the HSV of the color, and then convert to argb…?
Snippet of script below.
Thx,
Alan
#Create Random Color
def randomcolor():
red = int(255*random.random())
green = int(255*random.random())
blue = int(255*random.random())
return Color.FromArgb(red,green,blue)
#Define new layers (with names to be used throughout script)
bbox_layer_name = rs.AddLayer("bbox"+new_element, Color.FromArgb(20, 0, 0, 0), parent=new_element)
crv_layer_name = rs.AddLayer("crv"+new_element, Color.Red, parent=new_element)
sol_layer_name = rs.AddLayer("sol"+new_element, randomcolor(), parent=new_element)
I have a background in other languages just not GHPython. As I read the code it seemed like it provided a decent framework to work from and the script worked well, it also answered Alan’s questions so I posted it. Sure there may be more optimized ways to do things but I don’t think there’s anything wrong with using chatGPT to get ideas to move forward with. I’ve deleted it now, sorry for any offense it may have caused.
I ended up tweaking your solution a bit to allow a few additional controls, Saturation, Count, Seed, and ability to sort the color list by value.
I’m not quite happy with the value sorting as it appears (at least visually to me) that the sorting is slightly off (the V values are correct, but i think i need to take the saturation into account as well?)
My idea is to be able to generate a “random” color pallet and for now it’s close enough for my intent.
Thanks for sharing as always!
import random
import Rhino as rc
def generate_random_colors(C, H, S, V, Se):
# Assign specific inputs if provided, otherwise use defaults
C = C if C is not None else 4
H = H if H is not None else .5
S = S if S is not None else .5
V = V if V is not None else .5
Se = Se if Se is not None else 235
Rc = []
if Se is not None:
random.seed(Se)
for i in range(C):
rand_S = random.uniform(S, 1.0)
rand_V = random.uniform(V, 1.0)
hsv = rc.Display.ColorHSV(H, rand_S, rand_V)
rgb = hsv.ToArgbColor()
Rc.append((rgb, rand_V)) # Store both the RGB color and the corresponding V value
# Sort Rc by V value in descending order
RcS = sorted(Rc, key=lambda x: x[1], reverse=True)
# Extract the sorted RGB colors from the RcS list
RcS = [item[0] for item in RcS]
# Get RGB Colors from Rc list
Rc = [item[0] for item in Rc]
return Rc, RcS
Rc, RcS = generate_random_colors(C, H, S, V, Se)
random.random() creates random values between 0 and 1.0, which is what the h, s and v arguments are looking for. random.uniform(a,b) creates values between a and b and thus serves to limit the range. By supplying 0.6 to 1 as a range, the values (brightness) stay in the upper range.
From the Python docs:
random.random()
Return the next random floating point number in the range 0.0 <= X < 1.0
random.uniform(a, b )
Return a random floating point number N such that a <= N <= b for a <= b and b <= N <= a for b < a.
One could use the same strategy to limit the range of hues (h) or saturation (s)…
I added your snippet to my script (updating to LayerColor, as you did) and I’ve been working for a few minutes on a new problem: My intended new layer (“sol”+new_element…) isn’t being created. I believe I’m able to use the def as a parameter inside my rs.AddLayer(), correct?
Maybe it’s because I’m not “selecting” a layer to change, but creating one?
#Create Random Light Color
def random_color_light():
h=random.random()
s=random.uniform(0.2,0.3)
v=random.uniform(0.3,0.8)
rs.LayerColor(layer,Rhino.Display.ColorHSV(h,s,v).ToArgbColor())
#Create Layers named per user-submitted new_element
rs.AddLayer(name=new_element, parent=overall_parent)
bbox_layer_name = rs.AddLayer("bbox"+new_element, Color.FromArgb(20, 0, 0, 0), parent=new_element)
crv_layer_name = rs.AddLayer("crv"+new_element, Color.Red, parent=new_element)
sol_layer_name = rs.AddLayer("sol"+new_element, random_color_light(), parent=new_element)
EDIT: Ah, maybe b/c I don’t have the “for Layer in Layers…”
Yes, tho (probably separate topic) I’m planning on scripting it so the user can choose how many “sol” layers for the layer tree, and then each of those layers would get their own color
Yes maybe, it’s gets a bit “visual” if you will. I just took the liberty to simplify things a bit by using default function arguments and sorting by the HSV Value property directly, might help: