Micorsoftの色をBlenderで使う

Blender Pythonにて色指定するときに、どこからが赤で、どこからがオレンジで、どこまでが青で、どこまでが紫か、ちょっと私にはわからず、悩んでおりました。

各ソフトの色の変え方

Blender Pythonでの色の変え方

ご存じの通り、Blender Pythonで色を変えようとすると下記のようにR,G,BにFloatで1~0の数値をRGBに入れる方法でマテリアルなどの色を変えます。R,G,B,αの順です。

import bpy
# 指定例
bpy.data.materials["cube1"].node_tree.nodes["ColorRamp"].color_ramp.elements[0].color = (1, 0.5, 0.5, 1)   

しかし特に境目(閾値?)がないので、Floatで1~0の数値をRGBに入れる形は、色の命名が面倒です。

Excel VBAでの色の変え方

悩んでいたところで先日、エクセルVBAで色を指定するときのことを思い出しました。エクセルではRGB値による指定も出来ますが、142色を選ぶことも出来るようになっています。

' A1セルの色をアリスブルーに変える
Range("A1").Interior.Color = rgbAliceBlue
Range("A1").Interior.Color = 16775408
Range("A1").Interior.Color = RGB(240, 248, 255)
XlRgbColor 列挙型 (Microsoft.Office.Interop.Word)
RGB カラーを指定します。

ちなみに10進数⇔8bitの変換は以下。

$$RGB = R + {G}\times{256} + {B}\times{256^2}$$

AliceBlueの例だと…

$$16775408 = 240 + {248}\times{256} + {255}\times{256^2}$$

となります。

Tableで表すとこんな感じ

”赤”ですと、Rが最大の255(0始まりなので256ではない)となることから、256で割って0~1にスケーリングします。

id名前10進数値説明R(8bit)G(8bit)B(8bit)R(0~1)G(0~1)B(0~1)color name
1rgbAliceBlue16775408アリスブルー2402482550.9411764710.972549021AliceBlue
2rgbAntiqueWhite14150650アンティークホワイト2502352150.9803921570.9215686270.843137255AntiqueWhite
3rgbAqua16776960水色0255255011Aqua
4rgbAquamarine13959039アクアマリン1272552120.49803921610.831372549Aquamarine
5rgbAzure16777200空色2402552550.94117647111Azure
csvを一部抜粋

これをPythonから読み込み、color nameで指定して戻り値でRGB値を0~1で受けることができる関数を作りました。

PandasでRead

Pandasを使用しますので、あらかじめinstallしておいてください。(PYTHONPATHの設定もお忘れなく)

import pandas as pd

def Get_RGB_0to1lis_ms(color_name):
    
    url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
    df = pd.read_csv(url, 
                encoding='utf-8' ,
                sep=',' , 
                index_col=None
                )
    RGB_0to1lis = df[df['color name']==color_name]
    return [RGB_0to1lis['R(0~1)'].values[0],
            RGB_0to1lis['G(0~1)'].values[0],
            RGB_0to1lis['B(0~1)'].values[0]]

RGB_0to1lis = Get_RGB_0to1lis_ms('DarkBlue')
# RGB_0to1lis is [0	0	0.545098039] when color_name='DarkBlue'

そして、ちょっとユニークな仕様ですが、乱数発生の整数をid指定して、ランダムな色が出てくるような関数も面白いのでは、と思って作りました。

下記の例は1~143の乱数を発生させてCube1のColorRampのelement0の色を変えるものです。

import pandas as pd
import random
import bpy

def Get_RGB_0to1lis_ms_byId(id_number):
    # id number is 1 to 143
    url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
    df = pd.read_csv(url, 
                encoding='utf-8' ,
                sep=',' , 
                index_col=None
                )
    RGB_0to1lis = df[df['id']==id_number]
    colorname = RGB_0to1lis['color name'].values[0]
    
    return [RGB_0to1lis['R(0~1)'].values[0],
            RGB_0to1lis['G(0~1)'].values[0],
            RGB_0to1lis['B(0~1)'].values[0]] , colorname

[RGB_0to1lis,colorname] = Get_RGB_0to1lis_ms_byId(random.randint(1,143))

bpy.data.materials["cube1"].node_tree.nodes["ColorRamp"].color_ramp.elements[0].color = (RGB_0to1lis[0],
                                                                                         RGB_0to1lis[1],
                                                                                         RGB_0to1lis[2],
                                                                                         1)
id=1 アリスブルー

おまけ

ちょっと謎なんですが、同じ色でつづりが異なるものが7つあるのでその重複を削除する必要があるのでお気をつけて。

重複の項目

143色→128色となります。reset_indexメソッドを使いますが、0始まりになってしまい、指定の番号が一つずれるので注意。また、関数内もilocで取りに行くカタチになるので、value[0]の記述も必要なくなります。(最初からこの指定のほうがよかったカモ)

import pandas as pd

def Get_RGB_0to1lis_ms_byId_noDup(df,id_number):
    # id number is 0 to 127

    RGB_0to1lis = df.iloc[id_number,:]
    colorname = RGB_0to1lis['color name']
    
    return [RGB_0to1lis['R(0~1)'],
            RGB_0to1lis['G(0~1)'],
            RGB_0to1lis['B(0~1)']] , colorname

url = 'https://chanyoguitar.net/wp-content/uploads/2022/11/ColorTable_ms.csv'
df_org = pd.read_csv(url, 
            encoding='utf-8' ,
            sep=',' , 
            index_col=None
            )
df = df_org[~df_org.duplicated(keep=False,subset='10進数値')]
df.reset_index(drop=True, inplace=True) # index reset (この処理が入ると0始まりになる)
[RGB_0to1lis,colorname] = Get_RGB_0to1lis_ms_byId_noDup(df,2) 
# RGB_0to1lis is [0	1 1] when color_name='Aqua'

余談ですが、調べてみるとExcel 2003までは、ワークシート上で表示できる色は56色だけのようで、機能が限られているが故、色の定義も簡単にできた時代だったんですかね。

皮肉だよね。全てを与えられると、何も出来ず、緩やかに死ぬなんて。

五条先生が言ってた。floatでほぼ無限の色を手に入れたことで、どこからが赤かわからなくなった人の一つのアイディアでした。

コメント

タイトルとURLをコピーしました