オリジナル雑貨の販売中

【初心者向け】FreeCADとPythonで作る!3Dプリント対応のリアルなサイコロの作り方

Bell
記事内に商品プロモーションを含む場合があります

3Dプリンターの普及により、自宅でオリジナルアイテムを作る楽しみが広がっています。今回は、**無料の3D CADソフト「FreeCAD」**を使って、**リアルな6面体サイコロ(ダイス)**を作成する方法をご紹介します。

Pythonスクリプトを使うことで、寸法やデザインの調整がしやすく、角が丸く・目が凹んでいる実用的なデータを簡単に作ることが可能になります。3Dプリントにもそのまま使えるモデルに仕上がるので、オリジナルサイコロを作ってみたい方にはピッタリの内容です。


サイコロ作成に必要なツール

今回使用するのは以下の2つだけです。

  • FreeCAD(最新版)
    オープンソースの3D CADソフト。Windows / macOS / Linux に対応。公式サイトから無料でダウンロードできます。
  • Python(FreeCAD内蔵)
    FreeCADにはPythonスクリプト機能が標準搭載されており、マクロや自動モデリングに便利です。

インストール後、FreeCADの「マクロ」機能からスクリプトを実行するだけで、サイコロの3Dモデルが完成します。


今回作るサイコロの特徴

作成するサイコロは以下のような仕様になっています:

  • 対面の目の合計が「7」
  • 目(ピップ)は凹んだデザイン
  • 角はフィレットで丸め処理

実際のサイコロと同様、目の配置にもこだわっており、見た目にも実用的なデザインになっています。


目の配置ルールと正確なモデリング

サイコロの面は1〜6の数字で構成されており、対面同士の合計が7になるように設計されています。

面の数字対面の数字
16
25
34

このルールに沿って、各面の中心位置や向きに基づいてピップ(目)を配置していきます。立方体の各面の中心点と法線ベクトルをもとにして、凹ませる球体を配置することで、立体的な目を再現しています。


フィレット(角丸)で柔らかい見た目に

サイコロは転がして使うアイテムなので、エッジが鋭いと手を傷つけたり、家具を傷めることもあります。そこで、FreeCADのフィレット機能を使って、全12辺の角を滑らかに処理しています。

これは見た目の美しさだけでなく、安全性や耐久性にもつながる大切な工程です。


凹みの目(ピップ)はどう作る?

目の部分は球体を作成し、それをサイコロ本体から**差し引く(Boolean Difference)**ことで、リアルな凹みを表現しています。

この方式は、

  • ✅ 実際のサイコロに近い見た目
  • ✅ 3Dプリント時のサポート材の削減
  • ✅ 着色しやすい構造

という利点があります。しかもスクリプトで自動化されているので、変更も簡単。たとえば目の深さやサイズを変えたいときも、数値を修正するだけで調整可能です。


出力と3Dプリントへの応用

完成したモデルは、FreeCADからSTL形式でエクスポートすることで、一般的な3Dプリンターに対応できます。

凹みがしっかりしているので、色分けもやりやすく、仕上がりの美しさも抜群です。


応用アイデア:自分だけのオリジナルサイコロへ

このサイコロの作り方をベースに、以下のような応用も可能です:

  • 🎲 12面体・20面体などの多面サイコロ
  • 🎨 表面に数字や記号を彫刻
  • 🧒 子供向けの教育サイコロ(絵柄入りや言葉入り)
  • 🌟 空洞構造の軽量サイコロ(内部をくり抜き)
  • 😈 重心を変えてイカサマサイコロ

FreeCAD + Python の組み合わせは柔軟性が高く、デザインの自由度が非常に高いのが特徴です。


まとめ:Pythonを活用したFreeCADの自動モデリングは超便利!

今回の方法では、FreeCADとPythonを組み合わせて、フィレット付き・凹み付きサイコロを簡単に自動生成できました。

手動でのモデリングだと時間がかかるような処理も、スクリプトを使えば再利用も一瞬。寸法やデザインの変更にも強く、繰り返し使えるテンプレートとして非常に便利です。

今後もこうしたPythonスクリプトによる自動モデリングを活用して、オリジナルアイテムをどんどん作ってみてはいかがでしょうか?


おまけ

📌 FreeCADのマクロ機能にスクリプトを貼り付けて実行するだけでOK!
興味のある方は、ぜひ一度試してみてくださいね。

以下をマクロにコピー&ペースト

import FreeCAD as App
import FreeCADGui as Gui
import Part

doc = App.newDocument("Dice_Rounded_Indented")

# サイズ・設定
dice_size = 20
pip_radius = 1.5
pip_distance = 5
pip_depth = 1.0
fillet_radius = 1.5

# 元のキューブ作成
cube = Part.makeBox(dice_size, dice_size, dice_size)

# 角を丸める(フィレット適用)
# まず形状をBodyとして扱う
shape = cube
edges_to_fillet = [e for e in shape.Edges]
cube_with_fillet = shape.makeFillet(fillet_radius, edges_to_fillet)

# 表示用にセット
cube_obj = Part.show(cube_with_fillet)
cube_gui = Gui.getDocument(doc.Name).getObject(cube_obj.Name)
cube_gui.ShapeColor = (1.0, 1.0, 1.0)  # 白

# 対面=7の目割り当て
face_data = {
    1: ((dice_size/2, dice_size/2, dice_size), (0, 0, 1)),
    6: ((dice_size/2, dice_size/2, 0), (0, 0, -1)),
    2: ((dice_size/2, dice_size, dice_size/2), (0, 1, 0)),
    5: ((dice_size/2, 0, dice_size/2), (0, -1, 0)),
    3: ((dice_size, dice_size/2, dice_size/2), (1, 0, 0)),
    4: ((0, dice_size/2, dice_size/2), (-1, 0, 0))
}

# ピップの配置
pip_patterns = {
    1: [(0, 0)],
    2: [(-pip_distance, -pip_distance), (pip_distance, pip_distance)],
    3: [(-pip_distance, -pip_distance), (0, 0), (pip_distance, pip_distance)],
    4: [(-pip_distance, pip_distance), (-pip_distance, -pip_distance),
        (pip_distance, pip_distance), (pip_distance, -pip_distance)],
    5: [(-pip_distance, pip_distance), (-pip_distance, -pip_distance), (0, 0),
        (pip_distance, pip_distance), (pip_distance, -pip_distance)],
    6: [(-pip_distance, pip_distance), (-pip_distance, 0), (-pip_distance, -pip_distance),
        (pip_distance, pip_distance), (pip_distance, 0), (pip_distance, -pip_distance)]
}

# 凹み球体の収集
all_pips = []

for face_num, positions in pip_patterns.items():
    center, normal = face_data[face_num]
    for x, y in positions:
        # ピップ位置を3D空間で算出(凹み分だけ奥に)
        if abs(normal[2]) == 1:  # Z面
            pos = App.Vector(center[0] + x, center[1] + y, center[2] - pip_depth * normal[2])
        elif abs(normal[1]) == 1:  # Y面
            pos = App.Vector(center[0] + x, center[1] - pip_depth * normal[1], center[2] + y)
        else:  # X面
            pos = App.Vector(center[0] - pip_depth * normal[0], center[1] + x, center[2] + y)

        # 凹み用球体(差分用)
        pip_cut = Part.makeSphere(pip_radius, pos)
        all_pips.append(pip_cut)

# サイコロからピップを差し引く
for pip in all_pips:
    cube_with_fillet = cube_with_fillet.cut(pip)

# 差し引き後のサイコロを再表示
doc.getObject("Shape").Shape = cube_with_fillet
doc.recompute()
ABOUT ME
Bell
Bell
CAEエンジニア
物理系修士卒。BtoBメーカーの機構設計開発業務を経験。
3D-CAD・CAEに出会い、コンピュータ上でのアイデアを具現化できる面白さに惹かれて、社内のCAD・CAE推進部署に異動して現職。

猫に囲まれて暮らすのが夢🐈🐈🐈
記事URLをコピーしました