BlenderPythonスクリプト、柔らか物体クロースオブジェクト、マテリアル追加、Collisionは重い
柔らか物体クロースオブジェクト記録
ファイル:fall_Cloth_Otoshi_colorMaterial_003.py
BlenderPythonスクリプトでは、複数の色マテリアルを新規作成(属性はなし)、オブジェクトに付与した。以前作ったスクリプトは、マテリアルを新規作成してそのまま新規オブジェクトに付与するスクリプトだった。今回は、先にマテリアルを新規作成して後で、オブジェクトに付与するもの。単にappendすればよいだけだった。
なお、クロースは初期設定で250フレームまでしか計算してくれない。これはクロースのCashキャッシュのところに、End終了フレーム指定があるのでここを変更することで250フレームを超えて計算してくれる。
今回15個ほどクロースオブジェクトを上方から落下させて物理演算の計算をさせたらかなり時間がかかった。Collisionが原因で、15個に個別にCollision衝突判定を加えているから処理が重い、遅い。Collisionがないときはサクッと終わる。当然の計算処理だろう。1フレーム再生するのに、1秒から5秒もかかった(通常は滑らかに秒24フレーム再生されるのに、数フレームから0.2フレームという処理の遅さ)。なので、個数は少なめにして実験したほうが良さそう。CPUがCorei7だからかもしれん。一度計算させたらキャッシュに残るからあとは速い
画像、映像
BlenderPythonスクリプト、複数の色マテリアルを新規作成(属性はなし)
- import os
- import bpy
- import math
- import copy
- import time
- import inspect#関数名を出力するためだけのもの
- #2024/10/21
- #print文はBlenderのメニューバーの Window > Toggle System Consoleを実行するとDOS窓が表示される
- #15個にクロースとCollisionを与えたので非常にアニメーションキャッシュ作成に時間がかかった。15個にCollisionを与えないと
- #サクッと終わるので、Collisionが処理を重くしてる。
- #Cloth物体を落として パチンコ台みたいに落ちる様子を観察する
- #落下物は高さを調整して落とす
- #\ / みたいな板を配置して上から落としていく
- #板 原点
- def funcMakePlane(resizeValue,loc):
- #resizeValue =value=(-5, -5, -5) リサイズのところのX軸側を大きくする予定
- bpy.ops.mesh.primitive_plane_add(size=2, enter_editmode=False, align='WORLD', location=loc, scale=(1, 1, 1))
- bpy.ops.transform.resize(value=resizeValue, orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL', mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', proportional_size=1, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'}, use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)
- #bpy.ops.rigidbody.object_add()
- #bpy.context.object.rigid_body.type = 'PASSIVE'
- bpy.ops.object.modifier_add(type='COLLISION')
- bpy.context.object.collision.absorption = 0.1
- #BOX Cube
- def funcMakeBox(resizeValue,loc):
- #BOXの生成位置の変更はlocation=(0, 2.5, 1)を変更する。サイズは現在value=(7.0, 1, 1)X軸に大きくしてる。正確に測っていない。2024/10/18
- bpy.ops.mesh.primitive_cube_add(size=2, enter_editmode=False, align='WORLD', location=loc, rotation=(0, 0, 0), scale=(1, 1, 1))
- bpy.ops.transform.resize(value=resizeValue, orient_type='GLOBAL', orient_matrix=((1, 0, 0), (0, 1, 0), (0, 0, 1)), orient_matrix_type='GLOBAL',\
- constraint_axis=(True, False, False), mirror=False, use_proportional_edit=False, proportional_edit_falloff='SMOOTH', \
- proportional_size=1, use_proportional_connected=False, use_proportional_projected=False, snap=False, snap_elements={'INCREMENT'},\
- use_snap_project=False, snap_target='CLOSEST', use_snap_self=True, use_snap_edit=True, use_snap_nonedit=True, use_snap_selectable=False)
- bpy.ops.object.modifier_add(type='COLLISION')
- bpy.context.object.collision.absorption = 0.1
- #球体 Cloth設定の引数が多すぎ,color,colorNameを追加、2024/10/21
- def funcMakeSphere(loc,tension_stiffness,compression_stiffness,uniform_pressure_force,pressure_factor,collision_settings_distance_min,materialColor):
- #glocation=loc#(0, 0, 2)Z軸に2m固定、X軸に並べていく
- bpy.ops.mesh.primitive_uv_sphere_add(radius=1, enter_editmode=False, align='WORLD', location=loc, scale=(1, 1, 1))
- #オブジェクトにマテリアルの要素を追加する
- #bpy.context.object.data.materials.append(mat)
- bpy.context.object.data.materials.append(bpy.data.materials[materialColor])
- #サンプル
- #bpy.ops.material.new()
- #bpy.data.materials[1].name='Material.001'
- #bpy.data.materials['Material.001'].diffuse_color=(1,0,0,1)
- #bpy.context.object.data.materials.append(bpy.data.materials['Material.001'])
- #サンプル
- #DataMaterials = bpy.data.materials
- #for key, value in DataMaterials.items():
- # print(f"[{key}] {value}")
- #Tension引張力 compression 圧縮,押し縮める押しつぶす小さくする pressure圧力 Stiff硬さ、曲がりにくい
- #bpy.context.space_data.context = 'MODIFIER'
- bpy.ops.object.modifier_add(type='CLOTH')
- bpy.context.object.modifiers["Cloth"].settings.tension_stiffness = tension_stiffness#15
- bpy.context.object.modifiers["Cloth"].settings.compression_stiffness = compression_stiffness#15
- bpy.context.object.modifiers["Cloth"].settings.use_pressure = True
- bpy.context.object.modifiers["Cloth"].settings.uniform_pressure_force = uniform_pressure_force#0.05
- bpy.context.object.modifiers["Cloth"].settings.pressure_factor = pressure_factor#30
- bpy.context.object.modifiers["Cloth"].collision_settings.distance_min = collision_settings_distance_min#0.015
- bpy.context.object.modifiers["Cloth"].point_cache.frame_end = 900#ここは、球体の数で可変にしたい。今は固定で対応
- bpy.ops.object.modifier_add(type='COLLISION')
- #end def
- def funcMakeTulip():
- pass
- def funcMakeMaterial():
- #ディクショナリで連想配列
- #赤 0.906,0.102,0.132,1.0
- # 橙 0.8,0.31,0.04,1.0
- # 黄0.8,0.78,0.245,1.0
- # 緑0.038,0.8,0.053,1.0
- # 青0.077,0.724,0.8,1.0
- # 藍0.047,0.055,0.8,1.0
- # 紫0.487,0.051,0.8,1.0
- #pink 0.907,0.681,0.837,1.0
- #白0.8,0.8,0.8,1.0
- #黒0.0,0.0,0.0,1.0
- #マテリアルを事前に作成しておく ディクショナリが見やすい
- gDipColorList={}
- gDipColorList["red"] =(0.906, 0.102, 0.132,1.0)
- gDipColorList["orange"] =(0.8, 0.31, 0.04,1.0)
- gDipColorList["yellow"] =(0.8, 0.78, 0.245,1.0)
- gDipColorList["green"] =(0.038, 0.8, 0.053,1.0)
- gDipColorList["bulue"] =(0.077, 0.724, 0.8,1.0)
- gDipColorList["indigo"] =(0.047, 0.055, 0.8,1.0)
- gDipColorList["purple"] =(0.487, 0.051, 0.8,1.0)
- gDipColorList["pink"] =(0.907, 0.681, 0.837,1.0)
- gDipColorList["white"] =(0.8, 0.8, 0.8,1.0)
- gDipColorList["black"] =(0.0, 0.0, 0.0,1.0)
- gColorList=[]#面倒だけど、番号で管理したい。他に良い方法があれば変更。今は面倒コードでいく2024/10/21
- gColorList.append(gDipColorList["red"] )
- gColorList.append(gDipColorList["orange"] )
- gColorList.append(gDipColorList["yellow"] )
- gColorList.append(gDipColorList["green"] )
- gColorList.append(gDipColorList["bulue"] )
- gColorList.append(gDipColorList["indigo"] )
- gColorList.append(gDipColorList["purple"] )
- gColorList.append(gDipColorList["pink"] )
- gColorList.append(gDipColorList["white"] )
- gColorList.append(gDipColorList["black"] )
- #keyList=list(gDipColorList.keys())#red,orangeのキー名を取得して、マテリアル名にする
- for m in gDipColorList.keys():
- mat = bpy.data.materials.new(m)
- mat.diffuse_color = gDipColorList[m]#color#t_color#(0.8, 0.8, 0.8, 1.0)
- # マテリアルスロットを追加する
- #bpy.ops.object.material_slot_add()
- ## 作成したマテリアルスロットに新規マテリアルを設定する
- bpy.context.object.active_material = mat
- #All
- def funcMatome():
- bpy.ops.object.mode_set(mode='OBJECT')
- funcMakeMaterial()#マテリアル作成
- materialColor= []#多分配列なので今はダミー
- dataMaterials = bpy.data.materials
- for key, value in dataMaterials.items(): #わざわざマテリアルを取得する必要があるかは疑問だけど今思いつくのはFor文
- if key=="Dots Stroke":
- pass
- else:
- materialColor.append(key)
- #print(key)
- gXlocation=0#球体のX座標位置初期値は原点
- gParamaterList=[]#クロースのパラメータ用配列
- #球体だけ複数作成、X軸に並べる 15個を超えると原点に戻す。なお30個以上の要素数は想定していない。理由は多すぎるから。
- #Tension引張力 compression 圧縮,押し縮める押しつぶす小さくする pressure圧力 Stiff硬さ、曲がりにくい
- # 1tension 2compression 3pressureForce 4factor distance
- gParamaterList.append([100, 15, 0.05, 30, 0.015])#(1)Tension大きめで硬い
- gParamaterList.append([100, 15, 0.05, 5, 0.015])#(1)硬い (4)factor弱めで凹む弾まない
- gParamaterList.append([15, 15, 0.05, 30, 0.015])#デフォルト設定
- gParamaterList.append([15, 15, 0.1, 30, 0.015])#(3)pressureForce
- gParamaterList.append([15, 15, 0.5, 30, 0.015])#(3)pressureForce 0.5以上で大きいと瞬時に膨張膨らむ 強め
- gParamaterList.append([15, 15, 1.0, 30, 0.015])#(3)pressureForce もっと強め
- gParamaterList.append([15, 15, 1.0, 60, 0.015])#(3)pressureForce もっと強めで膨張(4)factor大きくすると弾む
- gParamaterList.append([15, 15, 0.05, 5, 0.015])#(4)factor弱めで凹む弾まない
- gParamaterList.append([15, 5, 0.05, 5, 0.015])#
- gParamaterList.append([5, 5, 0.05, 30, 0.015])#柔らか
- gParamaterList.append([5, 15, 0.05, 10, 0.015])#(2)compressionを少し多め
- gParamaterList.append([5, 40, 0.05, 10, 0.015])#(2)を大きくしたことで少し中が詰まったような柔らかさが減っている(ぎゅっと押し込んだような感じ)
- gParamaterList.append([5, 5, 0.05, 10, 0.015])#柔らかで、弾力がない雰囲気
- gParamaterList.append([5, 5, 0.05, 5, 0.015])#
- gParamaterList.append([5, 5, 0.008, 5, 0.015])#(3)pressureForceかなり低め(4)弱いで、ポニョポニョブヨブヨ
- #16個目からはこっちに記載
- #チューリップ生成
- #板生成
- #gKakudai=len(gParamaterList)#数が多くなる事にX軸に対して板のサイズをX軸方向に拡大していく
- resizeValue =(-5, -10, -5) #Y軸にも拡大
- loc =(0.0, 0.0, 0.0)#ずらすX座標はあいまいなので調整が必要
- funcMakePlane(resizeValue,loc)
- #球体生成
- loc=(0,0,0)
- ylocation=1.0#手前の奥行き
- zAddLoction=10.0#g=9.8m = 10m
- zlocation=0.0#高さ
- zlocation=zAddLoction
- #yMoveLocation=-2.0
- #defaultFrame=20
- #localFrame=defaultFrame
- iCount=0
- #keyList=list(gDipColorList.keys())#red,orangeのキー名を取得して、マテリアル名にする
- for i in range(len(gParamaterList)):
- #原点のZ上方にオブジェクトを配置して落とす。変更するのはzLocationのみ
- loc=(gXlocation, 0, zlocation)#球体作成、配置、設定Z軸に初期3m固定、X軸に並べていく
- print("gParamaterList[i][0]="+str(gParamaterList[i][0]))
- funcMakeSphere(loc,gParamaterList[i][0],gParamaterList[i][1],gParamaterList[i][2],gParamaterList[i][3],gParamaterList[i][4],materialColor[iCount])
- #print(materialColor[iCount])
- #gXlocation+=2.1
- zlocation+=zAddLoction
- #10個ごとに、色を最初REDに戻す、色が増えたら「9」を変更して。
- if i==0:
- iCount+=1
- elif (i % 9) == 0:
- iCount=0
- else:
- iCount+=1
- #end for
- bpy.context.scene.frame_end =int(60*len(gParamaterList))#250フレームで物理演算の動きが止まってしまったなんで?クロースの「cash」の終了ENDを変更
- #end def
- #class 各種パラメータ、設定値をカプセル化にして、更に配列にカプセルを挿入させることでコードの視認性をたかめる
- #funcMatome()内で使用する ※ 2024/10/17現在クラスは使っていない
- class ClassCapcelParamaterCloth:
- def __init__(self,kyori,objName,list) -> None:
- print("class const")
- self.kyori= kyori#オブジェクトのX座標
- self.objName= objName#Obj type name:Cylinder
- self.list= list#Wiggle2のStiffのパラメータ配列、ボーンの数だけ必要なので、ボーンの数はこの配列の要素数で自動で取得
- self.number= 0
- def __del__(self):
- print("del デストラクタ、何もしないけど")
- def myNamePrint(self):# class 自分自身 出力
- function_name = inspect.currentframe().f_code.co_name# この部分は関数中でPrintで使える
- class_name = self.__class__.__name__
- print('{}.{}'.format(function_name, class_name))
- #end Class
- if __name__ == "__main__":
- print("*************************************************")
- print("*************************************************")
- print("****************** Start ***********************")
- #main GO
- # 3Dカーソルの位置を元に戻す
- bpy.context.scene.cursor.location=(0.0,0.0,0.0)
- funcMatome()
- print("****************** end ***********************")

株式ランキング

にほんブログ村

にほんブログ村