Porównaj commity

...

10 Commity

Autor SHA1 Wiadomość Data
Ryvn 6d76eccfce
Merge pull request #10 from hc-psy/hc-psy-patch-1
Update README.md
2023-12-30 14:36:06 +08:00
Ryvn 8469c60d19
Update README.md 2023-12-30 14:35:54 +08:00
Ryvn 0681bffd55
Merge pull request #9 from hc-psy/dev
Dev
2023-12-30 14:00:20 +08:00
hc-psy 6918f8cdc7 [fix] role prompt 2023-12-30 13:57:09 +08:00
hc-psy 5adf135eeb [fix] register prevent re-registering 2023-12-30 13:47:00 +08:00
hc-psy bd35098b4f [fix] register prevent re-registering 2023-12-30 13:39:46 +08:00
hc-psy 94ef7319bd [fix] register prevent re-registering 2023-12-30 13:35:46 +08:00
hc-psy f0210aee44 [fix] register prevent re-registering 2023-12-30 13:31:17 +08:00
hc-psy 3e82d05f37 [fix] os and panel 2023-12-30 10:54:59 +08:00
hc-psy abbba42a5a [fix] open ai and pkg 2023-12-30 09:40:29 +08:00
8 zmienionych plików z 377 dodań i 306 usunięć

Wyświetl plik

@ -8,12 +8,11 @@ Introducing our newly developed Blender Add-on that harnesses the potential of O
### Key Features
- **Multi-Lingual Support:** Our user-friendly interface is not confined to a single language. Choose from English, Simplified Chinese, or Traditional Chinese for a comfortable and personalized user experience. Also, you can speak to your software in the language you're comfortable with!
- **Choose Your Model:** Take control of the AI you're working with. Our Add-on allows you to toggle between Chat GPT-3.5 and Chat GPT-4 models based on your preference or task complexity, surely, your accessibility and budget 💰.
- **Adjustable Creativity:** Enjoy flexibility in design with adjustable "creativity" settings. This allows you to control the randomness and creativity of the AI, offering results ranging from highly deterministic (0) to wildly creative (1). Having said that, 0 is recommended.
- **UI Features:** Our user-friendly interface lets you maintain chat history, delete them at will, view produced codes, and much more. Experience the verisimilar simplicity and convenience of OpenAI chat GPT within the comfort of your Blender workspace.
- **Speed and Robustness:** We take pride in our add-on's performance. Experience faster inference times compared to similar products, and witness more robust results, ensuring your creativity is never hindered.
* **Expanded Multi-Lingual Support**: We're breaking language barriers! Now switch seamlessly between English, Español, 繁體中文 (Traditional Chinese), 简体中文 (Simplified Chinese), or Français. Tailor your Blender experience to the language you're most comfortable with.
* **Model Selection at Your Fingertips**: Empower your creativity by choosing the right AI model for your project. Whether it's the versatile Chat GPT-3.5 or the advanced Chat GPT-4, pick the one that fits your project's complexity and budget.
* **Dial Up Your Creativity**: With adjustable creativity levels, you're in the driver's seat. Control how "out of the box" your AI thinks, with settings ranging from very literal (0) to highly imaginative (1). For precision work, we suggest sticking with 0.
* **Enhanced User Interface**: Enjoy a more intuitive and streamlined interface. Keep track of your chat history, effortlessly manage and view generated codes, and delete them as you wish. It's the OpenAI chat GPT experience, refined and integrated into your Blender workspace.
* **Optimized Performance**: Experience the blend of speed and reliability. Our latest version offers faster response times and even more robust outcomes, ensuring that your creative flow is always smooth and uninterrupted.
### Medium Report
[Report](https://medium.com/@ryvnollie/blender-x-chatgpt-a-guide-to-the-ai-powered-blender-add-on-cf5766084f8f)
@ -40,7 +39,7 @@ To install the Blender GPT, follow the steps below:
1. **Download the Add-on**
On the GitHub page for the Blender GPT, click on `Code`, then select `Download ZIP`. This will download a ZIP file of the repository to your computer.
Go to the <a href="https://github.com/hc-psy/blender-gpt/releases/tag/lastest">Blender GPT Releases</a> on GitHub and download the latest version's ZIP file.
2. **Install the Add-on in Blender**
@ -55,7 +54,7 @@ To install the Blender GPT, follow the steps below:
4. **Enter your OpenAI API Key**
Go to the Addon preferences menu and paste your OpenAI API key.
Go to the Addon preferences menu, paste your OpenAI API key, and choose your preferred language.
### Usage
@ -66,31 +65,27 @@ Follow the steps below to make the most out of the Blender GPT:
In the 3D View, press `N` to open the sidebar. You will find the `Blender GPT` tab here.
2. **Select Your Preferred Language**
You can choose the language of your user interface and prompt input in the Language tab. The options allow for a more user-friendly experience.
3. **Choose the Chat-GPT Model**
2. **Choose the Chat-GPT Model**
You have the option to select between the gpt-3 (i.e., gpt-3.5) or gpt-4 models in the `chat-gpt model` tab. However, please note that the gpt-4 model can only be selected if you have access to gpt-4 on OpenAI.
4. **Adjust Level of Model Creativity**
3. **Adjust Level of Model Creativity**
There is a 'creativity' tab that allows you to control the creativity level (from 0 to 1) of the generated results by GPT. By adjusting this setting, you can encourage more novel output by setting a higher value.
5. **Enter Prompt in Input Field**
4. **Enter Prompt in Input Field**
Type your commands in plain language, either in English or Chinese, in the input field, e.g., "create 500 cubes in random locations".
6. **Submit Command**
5. **Submit Command**
Click on the `Submit prompt` button. This action will generate and execute the Blender Python code based on your provided prompt.
7. **Review Generated Codes**
6. **Review Generated Codes**
By clicking on the text icon next to `GPT>`, you can view the Python code generated by the chatgpt model. If you're familiar with script writing, you can further edit this Python code for finer control. In case the generated code is of subpar quality, you can tweak it directly and rerun the execution.
8. **Deletion Options**
7. **Deletion Options**
There are two ways to delete dialogues. The first is to delete the result of the last conversation. In this case, the `Submit prompt` will change to `Regenerate Response` for a fresh output. The second method allows for deleting all dialogue history. This is useful if you prefer that future generated results are not partially based on previous dialogues.
@ -119,7 +114,7 @@ That's it! Now you can enjoy the convenience of the Blender GPT. Remember, Blend
1. **下載插件**
在 Blender GPT 的 GitHub 頁面上,點擊 `Code`,然後選擇 `Download ZIP`。這將把存儲庫的 ZIP 文件下載到您的電腦。或者前往release取得發行版
前往 GitHub 上的 <a href="https://github.com/hc-psy/blender-gpt/releases/tag/lastest">Blender GPT 發布頁面</a>,下載最新版本的 ZIP 檔案
2. **在 Blender 中安裝插件**
@ -134,7 +129,7 @@ That's it! Now you can enjoy the convenience of the Blender GPT. Remember, Blend
4. **輸入您的 OpenAI API 鍵**
轉到插件偏好設置菜單並粘貼您的 OpenAI API 密鑰。
轉到插件偏好設置菜單並粘貼您的 OpenAI API 密鑰並選擇偏好語言
### 使用
@ -144,31 +139,27 @@ That's it! Now you can enjoy the convenience of the Blender GPT. Remember, Blend
在3D視圖中`N` 打開側欄。您將在這裡找到 `Blender GPT` 標籤。
2. **選擇您的語言**
您可以在語言選項卡中選擇用戶界面和提示輸入的語言。選項讓使用者體驗更友好。
3. **選擇 Chat-GPT 模型**
2. **選擇 Chat-GPT 模型**
您可以在 `chat-gpt 模型` 選項卡中選擇 gpt-3即 gpt-3.5)或 gpt-4 模型。但請注意,只有在 OpenAI 上有 gpt-4 訪問權限的情況下才能選擇 gpt-4 模型。
4. **調整模型創造力水平**
3. **調整模型創造力水平**
'創意度' 選項卡允許您控制 GPT 生成結果的創造力水平(從 0 到 1。通過調整此設置您可以通過設定更高的值來鼓勵更多新的輸出。
5. **在輸入欄位輸入指令**
4. **在輸入欄位輸入指令**
在輸入欄位中以簡單的語言英語或中文輸入您的命令例如“在隨機位置創建500個立方體”。
6. **提交指令**
5. **提交指令**
點擊 `提交指令` 按鈕。這將根據您提供的提示生成並執行 Blender Python 代碼。
7. **檢查生成的代碼**
6. **檢查生成的代碼**
點擊 `GPT>` 旁邊的文字圖標,您可以查看 chatgpt 模型生成的 Python 代碼。如果您熟悉腳本編寫,可以進一步編輯這個 Python 代碼以獲得更細致的控制。如果生成的代碼質量不高,您可以直接進行調整並重新執行。
8. **刪除選項**
7. **刪除選項**
有兩種刪除對話的方式。第一種是刪除上次對話的結果。在這種情況下,`提交指令` 將變為 `重新生成`,以便生成新的輸出。第二種方法可以刪除所有對話歷史。如果您希望未來生成的結果不會部分基於之前的對話,這將非常有用。

Wyświetl plik

@ -11,7 +11,7 @@ bl_info = {
"author": "Ryvn (@hc-psy) (@@hao-chenglo2049)",
"description": "",
"blender": (2, 82, 0),
"version": (0, 0, 1),
"version": (0, 0, 2),
"warning": "",
"category": "Object"
}

205
gpt_cst.py 100644
Wyświetl plik

@ -0,0 +1,205 @@
SYSTEMPROMPTS = [
"""
I am acting as a professional 3D artist skilled in scripting within Blender, the 3D software. My expertise lies in understanding the relationship between conceptual 3D models, animation ideas, and their corresponding Python scripts in Blender.
Here are the guidelines for our interaction:
- I will only respond with Python code relevant to Blender scripting, enclosed in markdown code blocks (```).
- My responses will focus on importing complete modules rather than individual components for scripting.
- I'll ensure to avoid destructive operations on meshes in my code suggestions.
- My responses will strictly adhere to the task at hand. I won't include additional setup like render settings or camera additions unless explicitly requested.
- My replies will consist solely of Python code without any additional explanations or comments.
This setup is designed for a tailor-made Blender GPT to assist with 3D modeling and animation scripting in Python.
""",
"""
Here are a few examples to illustrate how I can assist:
1. Task: Create 10 Cubes in Random Locations
- User Prompt Content: "Create 10 cubes in random locations from -1 to 1"
- Assistant Response Content:
```python
import bpy
import random
count = 10
for _ in range(count):
x = random.uniform(-1, 1)
y = random.uniform(-1, 1)
z = random.uniform(-1, 1)
bpy.ops.mesh.primitive_cube_add(location=(x, y, z))
```
2. Task: Delete All Mesh Objects and Create a Sphere
- User Prompt Content: Delete all mesh objects in the scene and create a 5x5x5 ball in the scene
- Assistant Response Content:
```python
import bpy
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_uv_sphere_add(location=(0, 0, 0), radius=2.5)
```
3. Task: Create a Rigid Body Simulation with a Tower of Cubes
- User Prompt Content: "Create a rigid body sim with 10 1x1x1 cubes stacked as a tower that falls down onto a 20x20 plane"
- Assistant Response Content:
```python
import bpy
for i in range(10):
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 1 + i))
bpy.ops.rigidbody.object_add()
bpy.context.object.scale = (1, 1, 1)
bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.context.object.scale = (20, 20, 1)
bpy.context.scene.frame_end = 200
```
"""
]
UI = {
'language': {
'zh': '繁體中文',
'cn': '简体中文',
'en': 'English',
'es': 'Español',
'fr': 'Français',
},
'label_language': {
'zh': '語言',
'cn': '语言',
'en': 'Language',
'es': 'Idioma',
'fr': 'Langue',
},
'label_model': {
'zh': 'GPT 模型',
'cn': 'GPT 模型',
'en': 'GPT Model',
'es': 'Modelo GPT',
'fr': 'Modèle GPT',
},
'label_model_description': {
'zh': '請選擇欲使用的GPT模型',
'cn': '请选择要使用的GPT模型',
'en': 'Please select the GPT model',
'es': 'Por favor seleccione el modelo GPT',
'fr': 'Veuillez sélectionner le modèle GPT',
},
'model_options': {
'zh': {
'gpt3.5': 'GPT-3.5 (便宜但較容易出錯)',
'gpt4': 'GPT-4 (昂貴但較詳細準確)',
},
'cn': {
'gpt3.5': 'GPT-3.5 (便宜但較容易出错)',
'gpt4': 'GPT-4 (昂贵但较详细准确)',
},
'en': {
'gpt3.5': 'GPT-3.5 (Affordable but less accurate)',
'gpt4': 'GPT-4 (Expensive but more accurate)',
},
'es': {
'gpt3.5': 'GPT-3.5 (Asequible pero menos preciso)',
'gpt4': 'GPT-4 (Caro pero más preciso)',
},
'fr': {
'gpt3.5': 'GPT-3.5 (Abordable mais moins précis)',
'gpt4': 'GPT-4 (Coûteux mais plus précis)',
},
},
'label_history': {
'zh': '對話歷史紀錄',
'cn': '对话历史纪录',
'en': 'Chat History',
'es': 'Historial de chat',
'fr': 'Historique du chat',
},
'label_show_code': {
'zh': '顯示程式碼',
'cn': '显示代码',
'en': 'Show Code',
'es': 'Mostrar código',
'fr': 'Afficher le code',
},
'label_user': {
'zh': '指令>',
'cn': '指令>',
'en': 'Prompt>',
'es': 'Indicación>',
'fr': 'Indication>',
},
'button_send': {
'zh': '請稍候,模型正在編寫腳本...',
'cn': '请稍候,模型正在编写脚本...',
'en': 'Please wait, the model is writing the script...',
'es': 'Por favor espere, el modelo está escribiendo el script...',
'fr': 'Veuillez patienter, le modèle écrit le script...',
},
'button_submit': {
'zh': '送出指令',
'cn': '提交指令',
'en': 'Submit Prompt',
'es': 'Enviar indicación',
'fr': 'Soumettre l\'indication',
},
'button_regenerate': {
'zh': '重新生成',
'cn': '重新生成',
'en': 'Regenerate Response',
'es': 'Regenerar respuesta',
'fr': 'Régénérer la réponse',
},
'command': {
'zh': '指令',
'cn': '指令',
'en': 'Prompt',
'es': 'Indicación',
'fr': 'Indication',
},
'command_instruction': {
'zh': '請輸入指令',
'cn': '请输入指令',
'en': 'Please enter the command',
'es': 'Por favor ingrese la indicación',
'fr': 'Veuillez entrer l\'indication',
},
'button_delete_all': {
'zh': '刪除所有對話',
'cn': '删除所有对话',
'en': 'Delete History',
'es': 'Eliminar historial',
'fr': 'Supprimer l\'historique',
},
'button_delete': {
'zh': '刪除此回答',
'cn': '删除此回答',
'en': 'Delete This Response',
'es': 'Eliminar esta respuesta',
'fr': 'Supprimer cette réponse',
},
'creativity': {
'zh': '創意度',
'cn': '创意度',
'en': 'Creativity',
'es': 'Creatividad',
'fr': 'Créativité',
},
'no_openai_key_error': {
'zh': '錯誤: 沒有偵測到 OPENAI API Key請在插件設定中設定 OPENAI API Key',
'cn': '错误: 没有检测到 OPENAI API Key请在插件设置中设置 OPENAI API Key',
'en': 'Error: No OPENAI API Key detected, please set OPENAI API Key in the add-on preferences',
'es': 'Error: No se detectó ninguna clave de API de OPENAI, configure la clave de API de OPENAI en las preferencias del complemento',
'fr': 'Erreur: aucune clé API OPENAI détectée, veuillez définir la clé API OPENAI dans les préférences du module complémentaire',
},
'no_prompt_error': {
'zh': '錯誤: 請輸入指令',
'cn': '错误: 请输入指令',
'en': 'Error: Please enter the prompt',
'es': 'Error: Por favor ingrese la indicación',
'fr': 'Erreur: Veuillez entrer l\'indication',
},
}

Wyświetl plik

@ -1,69 +1,6 @@
import openai
from openai import OpenAI
import re
def SYS_MAIN_PROMPT(language): return f"""
I want you to act as a professional 3D artist who is proficient in writing scripts in Blender, the 3D software. And you know how the relationship between the conceptual 3D model and animation ideas and the corresponding python scripts.
Here are some rules you have to heed and follow:
- Respond with your answers in markdown (```).
- Preferably import entire modules instead of bits.
- Do not perform destructive operations on the meshes.
- Do not use cap_ends. Do not do more than what is asked (setting up render settings, adding cameras, etc)
- Do not respond with anything that is not Python code.
- Do not provide explanations and comments.
- The input might be in {language}.
"""
EX_1_USER = """create 10 cubes in random locations from -1 to 1"""
EX_1_ASSISTANT = """```
import bpy
import random
bpy.ops.mesh.primitive_cube_add()
count = 10
for _ in range(count):
x = random.randint(-1,1)
y = random.randint(-1,1)
z = random.randint(-1,1)
bpy.ops.mesh.primitive_cube_add(location=(x,y,z))
```"""
EX_2_USER = """delete all mesh objects in the scene and create a 5x5x5 ball in the scence"""
EX_2_ASSISTANT = """```
import bpy
bpy.ops.object.select_all(action='DESELECT')
bpy.ops.object.select_by_type(type='MESH')
bpy.ops.object.delete()
bpy.ops.mesh.primitive_uv_sphere_add(location=(0, 0, 0), radius=2.5)
```"""
EX_3_USER = """create a rigid body sim with 10 1x1x1 cubes stacked as a tower taht falls down onto a 20x20 plane"""
EX_3_ASSISTANT = """```
import bpy
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 9))
bpy.ops.rigidbody.object_add()
bpy.ops.transform.resize(value=(0.5, 0.5, 0.5))
for i in range(9):
bpy.ops.mesh.primitive_cube_add(location=(0, 0, 9+i+1))
bpy.ops.rigidbody.object_add()
bpy.ops.transform.resize(value=(.5, .5, .5))
bpy.ops.mesh.primitive_plane_add(location=(0, 0, 0))
bpy.ops.rigidbody.object_add()
bpy.context.object.rigid_body.type = 'PASSIVE'
bpy.ops.transform.resize(value=(10, 10, 1))
bpy.context.scene.frame_end = 200
```"""
from .gpt_cst import SYSTEMPROMPTS
def post_process(final_txt):
@ -76,31 +13,16 @@ def post_process(final_txt):
return final_txt
def chatgpt(context):
def chatgpt(context, api_key=''):
if not api_key:
raise Exception("Please provide an OpenAI API key")
scene = context.scene
lan = int(scene.lan)
languages = ['traditional chinese', 'simplified chinese', 'english']
models = [scene.model_0, scene.model_1, scene.model_2]
prompts = [scene.prompt_input_0,
scene.prompt_input_1, scene.prompt_input_2]
temperatures = [scene.t_0,
scene.t_1, scene.t_2]
# sys data preparation
messages = [{"role": "system", "content": SYS_MAIN_PROMPT(languages[lan])}]
messages.append(
{"role": "system", "name": "example_user", "content": EX_1_USER})
messages.append(
{"role": "system", "name": "example_assistant", "content": EX_1_ASSISTANT})
messages.append(
{"role": "system", "name": "example_user", "content": EX_2_USER})
messages.append(
{"role": "system", "name": "example_assistant", "content": EX_2_ASSISTANT})
messages.append(
{"role": "system", "name": "example_user", "content": EX_3_USER})
messages.append(
{"role": "system", "name": "example_assistant", "content": EX_3_ASSISTANT})
# sysprompt preparation
messages = [{"role": "system", "content": system_prompt}
for system_prompt in SYSTEMPROMPTS]
# add previous messages
for msg in scene.history[-8:]:
@ -108,44 +30,23 @@ def chatgpt(context):
messages.append(
{"role": "assistant", "content": "```\n" + msg.content + "\n```"})
else:
messages.append({"role": "user",
"content": msg.content})
messages.append({"role": "user", "content": msg.content})
# add the current user message
if messages[-1]["role"] != "user":
# add the current user message
messages.append({"role": "user", "content": "Please provide me with Blender (3D software) python code satisfying the following task: " +
prompts[lan] + ". \n. Do not provide with anything that is not Python code. Do not provide explanations and comments."})
formatted_message = f"Please provide me with Blender (3D software) python code satisfying the following task: {scene.prompt_input}. \n. Do not provide with anything that is not Python code. Do not provide explanations and comments."
messages.append({"role": "user", "content": formatted_message})
response = openai.ChatCompletion.create(
model=models[lan],
# send message to GPT
client = OpenAI(api_key=api_key)
response = client.chat.completions.create(
model=scene.model,
messages=messages,
temperature=temperatures[lan],
# stream=True,
max_tokens=2000,
temperature=scene.creativity,
)
try:
# events = []
# final_txt = ''
# # becuase stream = true so use delta to concatentate
# for e in response:
# if len(e['choices'][0]['delta']) == 0:
# continue
# if 'role' in e['choices'][0]['delta']:
# continue
# events.append(e)
# event_text = e['choices'][0]['delta']['content']
# final_txt += event_text
# print(final_txt, flush=True, end='\r')
# return post_process(final_txt)
final_txt = response['choices'][0]['message']['content']
final_txt = response.choices[0].message.content
return post_process(final_txt)
except IndexError:
return None
return ''

Wyświetl plik

@ -1,9 +1,10 @@
import bpy
from bpy.types import Operator
import openai
from .gpt_gpt import chatgpt
from .gpt_cst import UI
class BLENDERGPT_OT_DEL_MSG(Operator):
@ -12,7 +13,7 @@ class BLENDERGPT_OT_DEL_MSG(Operator):
bl_description = "delete message"
bl_options = {"REGISTER", "UNDO"}
msg_idx: bpy.props.IntProperty(name="訊息索引", default=0)
msg_idx: bpy.props.IntProperty(name="msg_idx", default=0)
def execute(self, context):
scene = context.scene
@ -45,14 +46,7 @@ class BLENDERGPT_OT_GPT_CODE(Operator):
def execute(self, context):
# text area
if int(context.scene.lan) == 0:
txt_name = '指令腳本.py'
elif int(context.scene.lan) == 1:
txt_name = '指令脚本.py'
else:
txt_name = 'prompt_script.py'
txt_name = 'prompt_script.py'
txt = bpy.data.texts.get(txt_name)
if txt is None:
@ -93,42 +87,26 @@ class BLENDERGPT_OT_SEND_MSG(Operator):
def execute(self, context):
scene = context.scene
# TODO: connect to GPT
# openai api key
prf = context.preferences
openai.api_key = prf.addons["blender-gpt"].preferences.openai_key
prf_openai_api_key = prf.addons["blender-gpt"].preferences.openai_key
lan = prf.addons["blender-gpt"].preferences.language
if not openai.api_key:
if int(context.scene.lan) == 0:
self.report(
{'ERROR'}, "錯誤: 沒有偵測到 OPENAI API Key請在插件設定中設定 OPENAI API Key")
elif int(context.scene.lan) == 1:
self.report(
{'ERROR'}, "错误: 没有检测到 OPENAI API Key请在插件设置中设置 OPENAI API Key")
else:
self.report(
{'ERROR'}, "Error: No OPENAI API Key detected, please set OPENAI API Key in the add-on preferences")
if not prf_openai_api_key:
self.report({'ERROR'}, UI['error_no_api_key'][lan])
return {'CANCELLED'}
scene.on_finish = True
# bpy.ops.wm.redraw_timer(type='DRAW_WIN_SWAP', iterations=1)
lan = int(context.scene.lan)
prompts = [scene.prompt_input_0,
scene.prompt_input_1, scene.prompt_input_2]
if len(scene.history) == 0 or scene.history[-1].type == 'GPT':
if prompts[lan] == "":
if lan == 0:
self.report({'ERROR'}, f"錯誤: 請輸入指令")
elif lan == 1:
self.report({'ERROR'}, f"错误: 请输入指令")
else:
self.report({'ERROR'}, f"Error: Please enter the prompt")
if scene.prompt_input == "":
self.report({'ERROR'}, UI['error_no_prompt'][lan])
scene.on_finish = False
return {'CANCELLED'}
try:
code_exe_blender = chatgpt(context)
code_exe_blender = chatgpt(context, api_key=prf_openai_api_key)
except Exception as e:
self.report({'ERROR'}, f"Error: {e}")
scene.on_finish = False
@ -137,10 +115,8 @@ class BLENDERGPT_OT_SEND_MSG(Operator):
if len(scene.history) == 0 or scene.history[-1].type == 'GPT':
msg = scene.history.add()
msg.type = 'USER'
msg.content = prompts[lan]
scene.prompt_input_0 = ""
scene.prompt_input_1 = ""
scene.prompt_input_2 = ""
msg.content = scene.prompt_input
scene.prompt_input = ""
if code_exe_blender:
msg = scene.history.add()

Wyświetl plik

@ -22,13 +22,10 @@ def python_exec():
if isWindows():
return os.path.join(sys.prefix, 'bin', 'python.exe')
elif isMacOS():
try:
# 2.92 and older
path = bpy.app.binary_path_python
except AttributeError:
# 2.93 and later
import sys
path = sys.executable
return os.path.abspath(path)
elif isLinux():
@ -39,17 +36,19 @@ def python_exec():
def installModule(packageName):
python_exe = python_exec()
try:
subprocess.call([python_exe, "import ", packageName])
except:
python_exe = python_exec()
# upgrade pip
subprocess.check_call([python_exe, "-c", "import " + packageName])
print(f"{packageName} already installed")
except subprocess.CalledProcessError:
# upgrade pip
subprocess.call([python_exe, "-m", "ensurepip"])
subprocess.call(
[python_exe, "-m", "pip", "install", "--upgrade", "pip"])
# install required packages
subprocess.call([python_exe, "-m", "pip", "install", packageName])
# install required packages and upgrade
subprocess.call([python_exe, "-m", "pip", "install",
"--upgrade", packageName])
installModule('openai')

Wyświetl plik

@ -1,29 +1,7 @@
import bpy
from bpy.types import Panel
UI_lan = {
'language': ['繁體中文', '简体中文', 'English'],
'label_language': ['語言', '语言', 'Language'],
'label_model': ['Chat-GPT 模型', 'Chat-GPT 模型', 'Chat-GPT Model'],
'label_model_description': ['請選擇欲使用的Chat-GPT模型', '请选择要使用的Chat-GPT模型', 'Please select the Chat-GPT model'],
'model_options': {
'gpt3.5': ['GPT-3.5 (便宜但較容易出錯)', 'GPT-3.5 (便宜但較容易出错)', 'GPT-3.5 (Affordable but less accurate)'],
'gpt4': ['GPT-4 (昂貴但較詳細準確)', 'GPT-4 (昂贵但较详细准确)', 'GPT-4 (Expensive but more accurate)'],
},
'label_history': ['對話歷史紀錄', '对话历史纪录', 'Chat History'],
'label_show_code': ['顯示程式碼', '显示代码', 'Show Code'],
'label_user': ['指令>', '指令>', 'Prompt>'],
'button_send': ['請稍候,模型正在編寫腳本...', '请稍候,模型正在编写脚本...', 'Please wait, the model is writing the script...'],
'button_submit': ['送出指令', '提交指令', 'Submit Prompt'],
'button_regenerate': ['重新生成', '重新生成', 'Regenerate Response'],
'command': ['指令', '指令', 'Prompt'],
'command_instruction': ['請輸入指令', '请输入指令', 'Please enter the command'],
'button_delete_all': ['刪除所有對話', '删除所有对话', 'Delete History'],
'button_delete': ['刪除此回答', '删除此回答', 'Delete This Response'],
'creativity': ['創意度', '创意度', 'Creativity'],
}
from .gpt_cst import UI
class BLENDERGPT_PT_PANEL(Panel):
@ -34,43 +12,33 @@ class BLENDERGPT_PT_PANEL(Panel):
bl_category = 'Blender GPT'
def draw(self, context):
layout = self.layout
addon_prefs = context.preferences.addons['blender-gpt'].preferences
lan = addon_prefs.language
lan_idx = int(context.scene.lan)
layout = self.layout
column = layout.column(align=True)
# language usage
row = column.row(align=True)
row.label(text=UI_lan['label_language'][lan_idx])
row.prop(context.scene, "lan", text="")
# language youre using
column.label(text=UI['language'][lan])
column.separator()
# model of chat gpt
column.label(text=UI_lan['label_model'][lan_idx])
if lan_idx == 0:
column.prop(context.scene, "model_0", text="")
elif lan_idx == 1:
column.prop(context.scene, "model_1", text="")
else:
column.prop(context.scene, "model_2", text="")
column.label(text=UI['label_model'][lan])
column.prop(context.scene, "model", text="")
column.separator()
# creativity
column.label(text=UI_lan['creativity'][lan_idx])
if lan_idx == 0:
column.prop(context.scene, "t_0", text="")
elif lan_idx == 1:
column.prop(context.scene, "t_1", text="")
else:
column.prop(context.scene, "t_2", text="")
column.label(text=UI['creativity'][lan])
column.prop(context.scene, "creativity", text="")
column.separator()
# history of chat
if len(context.scene.history) > 0:
column.label(text=UI_lan['label_history'][lan_idx])
column.label(text=UI['label_history'][lan])
box = column.box()
for index, message in enumerate(context.scene.history):
if message.type == 'GPT':
@ -89,7 +57,7 @@ class BLENDERGPT_PT_PANEL(Panel):
else:
row = box.row()
row.label(
text=f"{UI_lan['label_user'][lan_idx]}{message.content}")
text=f"{UI['label_user'][lan]}{message.content}")
if index == len(context.scene.history) - 2:
del_msg_op = row.operator(
@ -100,60 +68,54 @@ class BLENDERGPT_PT_PANEL(Panel):
# input of chat
if len(context.scene.history) == 0 or (len(context.scene.history) > 0 and context.scene.history[-1].type != 'USER'):
column.label(text=UI_lan['command'][lan_idx])
if lan_idx == 0:
column.prop(context.scene, "prompt_input_0", text="")
elif lan_idx == 1:
column.prop(context.scene, "prompt_input_1", text="")
else:
column.prop(context.scene, "prompt_input_2", text="")
column.label(text=UI['command'][lan])
column.prop(context.scene, "prompt_input", text="")
# send message
if len(context.scene.history) > 0 and context.scene.history[-1].type == 'USER':
button_label = UI_lan['button_send'][lan_idx] if context.scene.on_finish else UI_lan['button_regenerate'][lan_idx]
button_label = UI['button_send'][lan] if context.scene.on_finish else UI['button_regenerate'][lan]
else:
button_label = UI_lan['button_send'][lan_idx] if context.scene.on_finish else UI_lan['button_submit'][lan_idx]
button_label = UI['button_send'][lan] if context.scene.on_finish else UI['button_submit'][lan]
column.operator("gpt.send_msg", text=button_label, icon="PLAY")
column.separator()
column.operator("gpt.del_all_msg",
text=UI_lan['button_delete_all'][lan_idx], icon="TRASH")
text=UI['button_delete_all'][lan], icon="TRASH")
def model_props_generator(idx):
def model_props_generator():
lan = 'en'
return bpy.props.EnumProperty(
name=UI_lan['label_model'][idx],
description=UI_lan['label_model_description'][idx],
name=UI['label_model'][lan],
description=UI['label_model_description'][lan],
items=[
("gpt-3.5-turbo", UI_lan['model_options']['gpt3.5']
[idx], UI_lan['model_options']['gpt3.5'][idx]),
("gpt-4", UI_lan['model_options']['gpt4']
[idx], UI_lan['model_options']['gpt4'][idx]),
("gpt-3.5-turbo", UI['model_options'][lan]
['gpt3.5'], UI['model_options'][lan]['gpt3.5']),
("gpt-4", UI['model_options'][lan]['gpt4'],
UI['model_options'][lan]['gpt4']),
],
default="gpt-3.5-turbo",
)
def prompt_input_generator(idx):
def prompt_input_generator():
lan = 'en'
return bpy.props.StringProperty(
name=UI_lan['command'][idx],
description=UI_lan['command_instruction'][idx],
name=UI['command'][lan],
description=UI['command_instruction'][lan],
default="",
)
bpy.props.StringProperty(
name="a",
description="a",
default="",
)
def temperature_generator():
lan = 'en'
def temperature_generator(idx):
return bpy.props.FloatProperty(
name=UI_lan['creativity'][idx],
description=UI_lan['creativity'][idx],
name=UI['creativity'][lan],
description=UI['creativity'][lan],
default=0,
min=0,
max=1,
@ -161,33 +123,12 @@ def temperature_generator(idx):
def props_initialization():
bpy.types.Scene.history = bpy.props.CollectionProperty(
type=bpy.types.PropertyGroup)
bpy.types.Scene.lan = bpy.props.EnumProperty(
name="語言",
description="請選擇語言",
items=[
("0", "繁體中文", "繁體中文"),
("1", "简体中文", "简体中文"),
("2", "English", "英文"),
],
default="0",
)
bpy.types.Scene.model_0 = model_props_generator(0)
bpy.types.Scene.model_1 = model_props_generator(1)
bpy.types.Scene.model_2 = model_props_generator(2)
bpy.types.Scene.prompt_input_0 = prompt_input_generator(0)
bpy.types.Scene.prompt_input_1 = prompt_input_generator(1)
bpy.types.Scene.prompt_input_2 = prompt_input_generator(2)
bpy.types.Scene.t_0 = temperature_generator(0)
bpy.types.Scene.t_1 = temperature_generator(1)
bpy.types.Scene.t_2 = temperature_generator(2)
bpy.types.Scene.model = model_props_generator()
bpy.types.Scene.prompt_input = prompt_input_generator()
bpy.types.Scene.creativity = temperature_generator()
bpy.types.Scene.on_finish = bpy.props.BoolProperty(default=False)
bpy.types.PropertyGroup.type = bpy.props.StringProperty()
@ -196,14 +137,7 @@ def props_initialization():
def props_clear():
del bpy.types.Scene.history
del bpy.types.Scene.lan
del bpy.types.Scene.model_0
del bpy.types.Scene.model_1
del bpy.types.Scene.model_2
del bpy.types.Scene.prompt_input_0
del bpy.types.Scene.prompt_input_1
del bpy.types.Scene.prompt_input_2
del bpy.types.Scene.t_0
del bpy.types.Scene.t_1
del bpy.types.Scene.t_2
del bpy.types.Scene.model
del bpy.types.Scene.prompt_input
del bpy.types.Scene.creativity
del bpy.types.Scene.on_finish

Wyświetl plik

@ -1,5 +1,7 @@
import bpy
from bpy import props
from bpy.types import AddonPreferences
from .gpt_cst import UI
class BLENDERGPT_AddonPreferences(AddonPreferences):
@ -12,6 +14,69 @@ class BLENDERGPT_AddonPreferences(AddonPreferences):
subtype="PASSWORD",
)
languages = [
('en', "English", ""),
('es', "Español", ""),
('zh', "繁體中文", ""),
('cn', "简体中文", ""),
('fr', "Français", ""),
]
language: props.EnumProperty(
name="Language",
items=languages,
default='en',
description="Select your preferred language",
update=lambda self, context: self.update_language(context)
)
def draw(self, context):
layout = self.layout
layout.prop(self, "openai_key")
layout.prop(self, "language", text="Language")
def update_language(self, context):
if 'blender-gpt' not in bpy.context.preferences.addons.keys():
return
prefs = context.preferences.addons['blender-gpt'].preferences
lan = prefs.language
# model
current_model = getattr(context.scene, "model", "gpt-3.5-turbo")
bpy.types.Scene.model = bpy.props.EnumProperty(
name=UI['label_model'][lan],
description=UI['label_model_description'][lan],
items=[
("gpt-3.5-turbo", UI['model_options'][lan]
['gpt3.5'], UI['model_options'][lan]['gpt3.5']),
("gpt-4", UI['model_options'][lan]['gpt4'],
UI['model_options'][lan]['gpt4']),
],
default=current_model,
)
setattr(context.scene, "model", current_model)
# prompt_input
current_prompt_input = getattr(context.scene, "prompt_input", "")
bpy.types.Scene.prompt_input = bpy.props.StringProperty(
name=UI['command'][lan],
description=UI['command_instruction'][lan],
default=current_prompt_input,
)
setattr(context.scene, "prompt_input", current_prompt_input)
# creativity
current_creativity = getattr(context.scene, "creativity", 0)
bpy.types.Scene.creativity = bpy.props.FloatProperty(
name=UI['creativity'][lan],
description=UI['creativity'][lan],
default=current_creativity,
min=0,
max=1,
)
setattr(context.scene, "creativity", current_creativity)