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 ***********************")
株式ランキング
にほんブログ村
にほんブログ村