ChatGPTなどのいわゆるAIサービスが普及しつつあり、色々な事務仕事が簡単に自動化出来るようになりました。
私は普段3D CADを使って製品の形状を書いている訳ですが、一向にモデリングの自動化の気配を感じません。早く楽になって欲しいけど、実際自動化しようと思ったらどうやるんだろうという興味が湧いてきたので、簡単なもののモデルをPythonを使って書いてみようと思います。
今回書くモデルは観葉植物などの植木鉢の下に敷くあれ、受け皿のモデリングをPythonを使ってトライしたのちに、鉢のサイズに合わせて後から自動で変更出来るように作ってみます。
まずはコマンドプロンプトからライブラリをインストールします。
〜
pip install numpy numpy-stl
〜
今回作成したコードはこちらです。
〜
import numpy as np
from stl import mesh
import argparse
def create_complete_cylinder_with_depressions(diameter, height, filename='flower_saucer.stl'):
diameter = diameter +4
radius = diameter / 2.0
first_offset_radius = radius - 2
first_depth = 1
second_offset_radius = radius * 0.8
second_depth = height - 2
second_base_offset_radius = second_offset_radius - second_depth
num_points = 100
angles = np.linspace(0, 2 * np.pi, num_points, endpoint=False)
base_circle = np.array([np.cos(angles) * radius, np.sin(angles) * radius, np.zeros(num_points)]).T
top_circle = np.array([np.cos(angles) * radius, np.sin(angles) * radius, np.full(num_points, height)]).T
first_depression_top = np.array([np.cos(angles) * first_offset_radius, np.sin(angles) * first_offset_radius, np.full(num_points, height)]).T
first_depression_base = np.array([np.cos(angles) * first_offset_radius, np.sin(angles) * first_offset_radius, np.full(num_points, height - first_depth)]).T
second_depression_top = np.array([np.cos(angles) * second_offset_radius, np.sin(angles) * second_offset_radius, np.full(num_points, height - first_depth)]).T
second_depression_base = np.array([np.cos(angles) * second_base_offset_radius, np.sin(angles) * second_base_offset_radius, np.full(num_points, height - second_depth)]).T
data = np.zeros(num_points * 12, dtype=mesh.Mesh.dtype)
cylinder_mesh = mesh.Mesh(data, remove_empty_areas=False)
for i in range(num_points):
cylinder_mesh.vectors[i * 12] = np.array([base_circle[i], base_circle[(i + 1) % num_points], [0, 0, 0]])
cylinder_mesh.vectors[i * 12 + 1] = np.array([base_circle[i], top_circle[i], base_circle[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 2] = np.array([base_circle[(i + 1) % num_points], top_circle[i], top_circle[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 3] = np.array([top_circle[i], first_depression_top[(i + 1) % num_points], first_depression_top[i]])
cylinder_mesh.vectors[i * 12 + 4] = np.array([first_depression_top[(i + 1) % num_points ], top_circle[(i + 1) % num_points], top_circle[i]])
cylinder_mesh.vectors[i * 12 + 5] = np.array([first_depression_top[i], first_depression_base[i], first_depression_base[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 6] = np.array([first_depression_top[(i + 1) % num_points], first_depression_top[i], first_depression_base[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 7] = np.array([first_depression_base[i], first_depression_base[(i + 1) % num_points], second_depression_top[i]])
cylinder_mesh.vectors[i * 12 + 8] = np.array([first_depression_base[(i + 1) % num_points], second_depression_top[(i + 1) % num_points], second_depression_top[i]])
cylinder_mesh.vectors[i * 12 + 9] = np.array([second_depression_top[i], second_depression_base[i], second_depression_top[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 10] = np.array([second_depression_top[(i + 1) % num_points], second_depression_base[i], second_depression_base[(i + 1) % num_points]])
cylinder_mesh.vectors[i * 12 + 11] = np.array([second_depression_base[i], second_depression_base[(i + 1) % num_points], [0,0,height - second_depth]])
cylinder_mesh.save(filename)
def main():
parser = argparse.ArgumentParser(description="Generate an STL file for a cylinder with depressions.")
parser.add_argument("diameter", type=float, help="Diameter of the cylinder")
parser.add_argument("height", type=float, help="Height of the cylinder")
args = parser.parse_args()
create_complete_cylinder_with_depressions(args.diameter, args.height)
if __name__ == "__main__":
main()
〜
こちらのコードをstl_make_flower_saucer.pyという名前を付けて保存して
コマンドプロンプトから実行します。
ファイル名の後に 直径 高さ の情報を引数として入力します。
〜
python stl_make_flower_saucer.py 100 10
〜
stl_make_flower_saucer.pyが保存されているフォルダにflower_saucer.stlが生成されました。
直径100mm 高さ10mmの受け皿の3Dデータが出来ました。
引数を変えてあげると
Pythonを使って3Dデータを作成して
引数で形状変更をすることが出来ました。
今日は一旦ここまで。