本日はBlenderPython枠です。
筆者は現在教育機関で勤務しており、学生さんへのサポートツールなども作っています。(筆者が勝手に)
先日OpenAIのAPIを使用できるようにしましたが、これを使用することでChatGPTの機能をBlenderで使用することができます。
これによって学生にとって非常に強力なアシスタントを獲得することになりますが、問題点として筆者のチャージからトークンが消費されるということです。
GPT-4o miniの場合ほかのモデルに比べて非常に低コストで使用することができますが、例えば学生の数や、学生の使用量によってはとんでもないコストがかかる場合が想定できます。
このような問題を回避するために最も簡単な方法としては一定期間で使用できる処理の回数を制限することです。
これはChatGPTでも採用されており、利用回数上限が来た場合機能が制限されるという仕組み自体はありふれています。
今回はこの1日の処理実行回数を定義します。
なお、非常に原始的な方法であり、プログラミング知識が無くてもある一定以上のITスキルがある学生の場合簡単に上限回数を書き換えてしまえるので、実運用的には問題がありますが、今回想定している筆者環境ではそのリスクよりもどんどんツールを使えた方がよいと判断しています。(まぁ学生のアクティブラーニング的に見て、制限開放できるならやってみなって思っていますが)
〇環境
・Blender4.1
・Windows 11PC
〇Jsonファイルの作成
まずは初期状態を想定して保存ファイルが存在する場合はそれを読み込み、ない場合は作成する必要があります。
def get_json_path():
script_path = os.path.dirname(os.path.realpath(__file__))
return os.path.join(script_path, "usage_data.json")
def initialize_or_load_json():
json_path = get_json_path()
if not os.path.exists(json_path):
・・・ファイルが存在しない場合
else: #ファイルが存在する場合データを読み込む
with open(json_path, 'r') as json_file:
data = json.load(json_file)
return data
この関数ではパスを参照し、ファイルを探しています。
では次にファイルが存在しない場合にファイルを作成する処理です。
if not os.path.exists(json_path):
data = {
"life": 20,
"last_execution_date": datetime.now().strftime("%Y-%m-%d")
}
with open(json_path, 'w') as json_file:
json.dump(data, json_file)
ここではjsonファイルを作成しています。 JsonはキーとValueが紐づいており、内部にはlifeに対して20、llast_execution_dataに対して、実行したその日の日付が格納されるようになっています。
またファイルの確認後に、もし前回実行時と現在の日時が異なる場合Jsonデータを書き換えライフを20に回復させる処理を加えています。
def get_json_path():
script_path = os.path.dirname(os.path.realpath(__file__))
return os.path.join(script_path, "usage_data.json")
# 初期化、もしくはJSONデータを読み込む関数
def initialize_or_load_json():
json_path = get_json_path()
if not os.path.exists(json_path):
data = {
"life": 20,
"last_execution_date": datetime.now().strftime("%Y-%m-%d")
}
with open(json_path, 'w') as json_file:
json.dump(data, json_file)
else:
with open(json_path, 'r') as json_file:
data = json.load(json_file)
last_execution_date = datetime.strptime(data["last_execution_date"], "%Y-%m-%d")
current_date = datetime.now()
if last_execution_date.date() != current_date.date():
data["life"] = 20 # 日付が変わっていたらライフを20回復
data["last_execution_date"] = current_date.strftime("%Y-%m-%d")
with open(json_path, 'w') as json_file:
json.dump(data, json_file)
return data
ここではdataがjsonでの保存データとなります。
〇処理の実行前の判定
では保存ファイルのデータを使用して実行前に『実行できるのか?』という判定を行います。
これはBlender側でGUIを描くオペレータクラスのExecuteに処理を記述します。
最初はGPT側で翻訳する関数内に記述していましたが、可読性の意味でもボタンの表記と紐づけることは合理的です。
class OBJECT_OT_translate_collection_names(bpy.types.Operator):
bl_idname = "object.translate_collection_names"
bl_label = "Translate Collection Names"
def execute(self, context):
data = initialize_or_load_json()
if data["life"] > 0:
print("Starting to update collection and object names...") # デバッグ用メッセージ
for collection in bpy.data.collections:
update_collection_names(collection)
print("Finished updating collection and object names.") # デバッグ用メッセージ
data["life"] -= 1 # ライフを1減らす
save_json_data(data) # JSONデータを保存
else:
self.report({'WARNING'}, "Life is 0. Please wait until tomorrow to try again.")
return {'FINISHED'}
ライフが0である場合警告を表示さえることで、なぜ処理が動かなかったのかをユーザーに理解させるようにしています。
以上で1日の処理実行可能回数を定義することができました。
冒頭で述べた通り、実装としては書き換えができるためあまりよろしくなく本来はウェブ側などでユーザーIDと紐づけて管理すべきですが、今回は学生向けのためまぁよしとしています。
この実装としては例えば回答可能回数を指定してマークダウンのテストなど応用ができそうです。
本日は以上です。