Blender 選択したオブジェクトすべてにラティス設定をしてゆがませる

Blender 選択したオブジェクトすべてにラティス設定をしてゆがませる

必要となってコードを書いたので、重要部分のソースを張っておく。オペレータ化すると便利かもしれない。

適用前。

適用後。

random_modifyの引数を変更して効果をわかりやすくしたもの。

例としてスザンヌに適用したが、整然と建物や木が並んだ風景に対して適用するつもり。
今回は個別にばらばらに変形しているが選択オブジェクトまとめて一括変形も対応するつもり。

import bpy
import mathutils
import numpy as np

def create_fit_latice(obj: bpy.types.Object, name_prefix:str="MyLattice") -> bpy.types.Object:
    if obj.is_instancer:
        return None
    mod = None
    for m in obj.modifiers:
        if m.name == name_prefix or m.name.startswith(name_prefix + "."):
            mod = m
            break
    if mod is None:
        mod = obj.modifiers.new(name_prefix, 'LATTICE')
    if mod is None:
        # camera, light, etc..
        return None
    if mod.object is not None:
        bpy.data.objects.remove(mod.object, do_unlink=True)
        mod.object = None

    lattice = bpy.data.lattices.new(f"{name_prefix}{obj.name}")
    lattice_obj = bpy.data.objects.new(f"{name_prefix}{obj.name}", lattice)
    lattice_obj.matrix_world = obj.matrix_world.copy()        
        
    #vertices
    bpy.context.scene.collection.objects.link(lattice_obj)
    mod.object = lattice_obj
    return lattice_obj.data

def random_modify(lattice_data, intensity:float = 0.15, div_u:int=6, div_v:int=6, div_w:int=6):
    lattice_data.points_u = div_u
    lattice_data.points_v = div_v
    lattice_data.points_w = div_w
    for p in lattice_data.points:
        co: mathutils.Vector = p.co
        p.co_deform = p.co + mathutils.Vector((np.random.rand(3) - 0.5) * intensity)
    

objects = bpy.context.selected_objects
for o in objects:
    lattice_data = create_fit_latice(o)
    if lattice_data is not None:
        random_modify(lattice_data)

コメントを残す

Previous post MSX1風画像エラーチェックツール
Next post SubstanceDesigner:アルファ=1のピクセルを探す