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  ***********************")    



株式ランキング
株式ランキング にほんブログ村 株ブログ 株 デイトレードへ
にほんブログ村 にほんブログ村 デザインブログ 3DCGへ
にほんブログ村

このブログの人気の投稿

メモ、BlenderPythonスクリプトで参考になるオブジェクトや頂点の選択ツリー選択スクリプトリンクメモ

楽天証券、信用取引口座から楽天FX口座へ振替手順

10/15デイトレは、ジュース代を確保した、日経平均が4万200円超