kopia lustrzana https://github.com/hc-psy/blender-gpt
121 wiersze
3.7 KiB
Python
121 wiersze
3.7 KiB
Python
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.
|
|
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.
|
|
- Please write comments 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)
|
|
```"""
|
|
|
|
|
|
def post_process(final_txt):
|
|
final_txt = re.findall(
|
|
r'```(.*?)```', final_txt, re.DOTALL)[0]
|
|
|
|
final_txt = re.sub(
|
|
r'^python', '', final_txt, flags=re.MULTILINE)
|
|
|
|
return final_txt
|
|
|
|
|
|
def chatgpt(context):
|
|
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})
|
|
|
|
# add previous messages
|
|
for msg in scene.history[-8:]:
|
|
if msg.type == "GPT":
|
|
messages.append(
|
|
{"role": "assistant", "content": "```\n" + msg.content + "\n```"})
|
|
else:
|
|
messages.append({"role": "user",
|
|
"content": msg.content})
|
|
|
|
if messages[-1]["role"] != "user":
|
|
# add the current user message
|
|
messages.append({"role": "user", "content": "Please provide me with Blender (3D software) code regarding the following task: " +
|
|
prompts[lan] + ". \n. Do not respond with anything that is not Python code. Do not provide explanations. " + f"Wite code comment in {languages[lan]}."})
|
|
|
|
response = openai.ChatCompletion.create(
|
|
model=models[lan],
|
|
messages=messages,
|
|
temperature=temperatures[lan],
|
|
stream=True,
|
|
max_tokens=2000,
|
|
)
|
|
|
|
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)
|
|
|
|
except IndexError:
|
|
return None
|