0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

Blenderで隣り合う面に異なる色を割当(四色問題)

Last updated at Posted at 2022-01-05

隣り合う面に異なる色を割当

実用性は不明ですが、Blenderで面を色で区別する方法を紹介します。

平面で行う場合、四色問題と言われますが、この記事では順番に割り当てるだけなので、厳密に四色問題を解いてはいません。また、平面ではないので五色まで使うことにします。

完成図

スザンヌを例にして実行した画面です。オブジェクトはメッシュであれば何でも良いです。見た感じ四色までしか使ってませんね。

手順

  • 適当にオブジェクト(例:スザンヌ)を作成します。
  • 編集モードに入ります。
  • マテリアルのスロットを5つ用意します。
  • 5つのマテリアルスロットにPrincipled BSDFを作成し、Base Colorを変えます。
  • 面ごとに隣り合う面と異なるように、色を若番から割り当てます。
  • その色のマテリアルを面に設定します。
  • オブジェクトモードに戻ります。

Pythonプログラム

プログラムは下記です。オブジェクトを選択して、Scriptingワークスペースに貼り付けて実行してください。

import bmesh
import bpy

colors = [
    (1, 0.1, 0.1, 1),
    (0.1, 0.2, 1, 1),
    (0.8, 0.8, 0, 1),
    (0, 0.8, 0.1, 1),
    (0.8, 0.2, 0, 1),
]

# スザンヌ作成
bpy.ops.mesh.primitive_monkey_add()
# 編集モード
bpy.ops.object.mode_set(mode="EDIT")
obj = bpy.context.edit_object
bm = bmesh.from_edit_mesh(obj.data)

# マテリアルのスロットを5つ用意
for _ in range(len(colors) - len(obj.material_slots)):
    bpy.ops.object.material_slot_add()

# 5つのマテリアルを作成
for i, color in enumerate(colors):
    material = f"M{i}"
    mat = bpy.data.materials.get(material) or bpy.data.materials.new(name=material)
    mat.use_nodes = True
    mat.node_tree.nodes["Principled BSDF"].inputs["Base Color"].default_value = color
    obj.active_material_index = i
    obj.active_material = mat

# 面ごとに隣り合う面と異なるように、色を若番から割当
n = len(bm.faces)
res = [0] * n
dj = [[] for _ in range(n)]  # 面ごとの禁止領域リスト
for edge in bm.edges:
    if len(edge.link_faces) == 2:
        i = edge.link_faces[0].index
        j = edge.link_faces[1].index
        dj[max(i, j)].append(min(i, j))
for i in range(n):
    res[i] = ({1, 2, 3, 4, 5} - {res[j] for j in dj[i]}).pop()

# 色のマテリアルを面に設定
for face, i in zip(bm.faces, res):
    if i:
        obj.active_material_index = i - 1
        bpy.ops.mesh.select_all(action="DESELECT")
        face.select = True
        bpy.ops.object.material_slot_assign()
bm.free()
# オブジェクトモード
bpy.ops.object.mode_set(mode="OBJECT")

参考:BlenderでPythonを実行する方法

以上

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?