見出し画像

【Blender Python】平面でオブジェクトを分割する

前回の記事で、平面でオブジェクトを切断する方法を紹介しました。

これだと切断後の片側だけしか残らないので、今回は平面でオブジェクトを分割する方法を紹介しようと思います。

Blenderのバージョンは2.93 LTSです。

1. コード

import numpy as np
import bpy


# 既存のメッシュオブジェクトを削除
for msh in bpy.data.meshes:
   bpy.data.meshes.remove(msh)


# 3つの立方体を配置
bpy.ops.mesh.primitive_cube_add(location=(-3, 0, 0))
my_cube1 = bpy.context.object
my_cube1.name = 'cube_a_1'

bpy.ops.mesh.primitive_cube_add(location=(0, 0, 0))
my_cube2 = bpy.context.object
my_cube2.name = 'cube_b'

bpy.ops.mesh.primitive_cube_add(location=(3, 0, 0))
my_cube3 = bpy.context.object
my_cube3.name = 'cube_a_2'


# 平面を配置
verts = [[-5, -2, -1], [5, -2, -1], [5, 2, 1], [-5, 2, 1]]
faces1 = [[0, 1, 2, 3]]
faces2 = [[3, 2, 1, 0]]

msh1 = bpy.data.meshes.new("cubemesh1") #Meshデータの宣言
msh1.from_pydata(verts, [], faces1) # 頂点座標と各面の頂点の情報でメッシュを作成
my_plane1 = bpy.data.objects.new("plane1", msh1) # メッシュデータでオブジェクトを作成
bpy.context.scene.collection.objects.link(my_plane1) # シーンにオブジェクトを配置

msh2 = bpy.data.meshes.new("cubemesh2") #Meshデータの宣言
msh2.from_pydata(verts, [], faces2) # 頂点座標と各面の頂点の情報でメッシュを作成
my_plane2 = bpy.data.objects.new("plane2", msh2) # メッシュデータでオブジェクトを作成
bpy.context.scene.collection.objects.link(my_plane2) # シーンにオブジェクトを配置


# 分割するオブジェクトをリストに格納
obj_l = list()
for obj in bpy.data.objects:
   if 'cube_a' in obj.name:
       obj_l.append(obj)

for obj in obj_l:
   bpy.ops.object.select_all(action='DESELECT')
   obj.select_set(True)
   bpy.ops.object.duplicate(linked=False)
   obj_dup = bpy.data.objects[obj.name + '.001']
   obj_dup.name = obj.name + '_2'
   obj.name = obj.name + '_1'

   # Modifierを追加
   mod1 = obj.modifiers.new('bool1', 'BOOLEAN')
   mod1.operation = 'DIFFERENCE'
   mod1.object = my_plane1
   mod1.solver = 'EXACT'

   # Modifierを適用
   bpy.context.view_layer.objects.active = obj
   bpy.ops.object.modifier_apply(modifier='bool1')

   # Modifierを追加
   mod2 = obj_dup.modifiers.new('bool2', 'BOOLEAN')
   mod2.operation = 'DIFFERENCE'
   mod2.object = my_plane2
   mod2.solver = 'EXACT'

   # Modifierを適用
   bpy.context.view_layer.objects.active = obj_dup
   bpy.ops.object.modifier_apply(modifier='bool2')

# 不要な平面を除去
bpy.data.objects.remove(my_plane1, do_unlink=True)
bpy.data.objects.remove(my_plane2, do_unlink=True)

# 結果が分かりやすいように上側のオブジェクトをz軸方向にずらす
bpy.data.objects['cube_a_1_1'].location.z = 0.5
bpy.data.objects['cube_a_2_1'].location.z = 0.5

基本的には前回の応用です。

違う点は、
・分割したいオブジェクトを複製する
・分割に使う平面は裏表の2枚を用意する
・複製したオブジェクトのそれぞれを表向きの平面と裏向きの平面で切断する
というところです。

2. 実行結果

画像1

平面でオブジェクトが分割されているのが分かるかと思います。

結果が分かりやすいように、分割後の上側のオブジェクトをz軸方向に少しずらしてあります。

まとめ

複製後のオブジェクトにアクセスするときに、「元のオブジェクトの名前 + .001」を指定している部分などやや力技な感じもしますが、平面でオブジェクトを分割する方法を紹介しました。

もっといいやり方を知っている人は是非教えて下さい。

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