見出し画像

Blender×Pythonで3次元の格子点を作ってみた

(2021年9月20日 17:08 初出FB)
3次元の格子点を中から眺めたイメージ、できた! 地理院地図ファンクラブの共同主催者のIさんから「干渉色の立体中に飛び込むようなイメージ」の表現方法があるか、というご質問を某所でいただきました。。とても面白そうな「お題」をいただいたので、チャレンジ中。

まずは、Pythonを使い、Blenderで(x,y,z)の格子点に球を沢山配置して、中心の格子点の近くから眺めた様子が上の画像と下の画像です。

210920_3D格子点に入り込む2

あとは、ランダム色の配色を、各格子点のデータに応じて干渉色にしたら完成かも。。干渉色のRGB値の算出アルゴリズムは、すでにPythonで過去に作ったのがあるので、それを組み込めばOK。。今回のPythonのスクリプトは下記のとおりです。「ランダム色の600匹のサル」のスクリプトを改造してます。

# Draw uv_spheres in random colors on 3D glid-points in Blender using Python
# Pythonを使ってBlenderで格子点上にランダムの色で描く

import bpy
from random import randint
import numpy as np

# "def HSL_2_RGB" and "def Hue_2_RGB" ported "HSL → RGB" 
# from https://www.easyrgb.com/en/math.php to Python.

def HSL_2_RGB(H, S, L): # Function to convert HLS to RGB
   # H, S and L input range = 0 - 1.0
   # R, G and B output range = 0 - 1.0  # Changed 255 to 1.0
   if S == 0 :
       R = L * 1.0     # Changed 255 to 1.0
       G = L * 1.0     # Changed 255 to 1.0
       B = L * 1.0     # Changed 255 to 1.0
   else:
       if L < 0.5 : var_2 = L * ( 1 + S )
       else : var_2 = ( L + S ) - ( S * L )
   var_1 = 2 * L - var_2
   R = 1.0 * Hue_2_RGB( var_1, var_2, H + ( 1 / 3 ) )  # Changed 255 to 1.0
   G = 1.0 * Hue_2_RGB( var_1, var_2, H )              # Changed 255 to 1.0
   B = 1.0 * Hue_2_RGB( var_1, var_2, H - ( 1 / 3 ) )  # Changed 255 to 1.0
   return R, G, B

def Hue_2_RGB( v1, v2, vH ):    # Function to convert Hue to RGB
  if vH < 0 : vH += 1
  if vH > 1 : vH -= 1
  if 6 * vH < 1 : return ( v1 + ( v2 - v1 ) * 6 * vH )
  if 2 * vH < 1 : return ( v2 )
  if 3 * vH < 2 : return ( v1 + ( v2 - v1 ) * ( ( 2 / 3 ) - vH ) * 6 )
  return ( v1 )

def materialRandomColor(materialName='') :  # Function to make material
   material = bpy.data.materials.new(materialName)
   material.use_nodes = True 
   p_BSDF = material.node_tree.nodes["Principled BSDF"] 
   R, G, B = HSL_2_RGB(np.random.rand(1), 1.0, 0.5)    # Get RGB values of H = 0-1(random), S = 1, L = 0.5
   p_BSDF.inputs[0].default_value = (R, G, B, 1)       # RGBA
   p_BSDF.inputs[7].default_value = 0.05                  # Roughness
   p_BSDF.inputs[15].default_value = 0.8                 # Transmittance
   return material

# Add uv_spheres on 3D glid-points
number = 5
spaceRange = 50
for k in range(-number, number + 1, 1):
   for j in range(-number, number + 1, 1):
       for i in range(-number, number + 1, 1):
           x = i * spaceRange / ( 2 * number )
           y = j * spaceRange / ( 2 * number )
           z = k * spaceRange / ( 2 * number )
           materialName = 'Color' + str(i+j*10+k*100)
           material = materialRandomColor(materialName) 
           bpy.ops.mesh.primitive_uv_sphere_add(location=(x,y,z))
           bpy.context.object.data.materials.append(material)

この記事が気に入ったらサポートをしてみませんか?