From 0d655f2d18b6569614bce2d92e47a1f1efdddc0d Mon Sep 17 00:00:00 2001 From: qingxu fu <505030475@qq.com> Date: Mon, 10 Jul 2023 12:58:17 +0800 Subject: [PATCH] =?UTF-8?q?=E4=B8=89=E7=BB=B4=E5=9C=BA=E6=99=AF=E7=94=9F?= =?UTF-8?q?=E6=88=90?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- cc.json | 39 ++++++ crazy_functional.py | 13 ++ crazy_functions/Three场景交互3D.py | 166 ++++++++++++++++++++++++ crazy_functions/crazy_functions_test.py | 14 +- crazy_functions/crazy_utils.py | 2 + crazy_functions/vhmap_interact/vhmap.py | 38 ++++++ 6 files changed, 270 insertions(+), 2 deletions(-) create mode 100644 cc.json create mode 100644 crazy_functions/Three场景交互3D.py create mode 100644 crazy_functions/vhmap_interact/vhmap.py diff --git a/cc.json b/cc.json new file mode 100644 index 00000000..3b367886 --- /dev/null +++ b/cc.json @@ -0,0 +1,39 @@ +[ + { + "name": "Box-1", + "width": 1, + "height": 1, + "depth": 1, + "location_x": 1, + "location_y": 0, + "location_z": 0 + }, + { + "name": "Box-2", + "width": 1, + "height": 1, + "depth": 1, + "location_x": -1, + "location_y": 0, + "location_z": 0 + }, + { + "name": "Box-3", + "width": 1, + "height": 1, + "depth": 1, + "location_x": 0, + "location_y": 1, + "location_z": 0 + }, + { + "name": "Box-4", + "width": 1, + "height": 1, + "depth": 1, + "location_x": 0, + "location_y": -1, + "location_z": 0 + } + +] \ No newline at end of file diff --git a/crazy_functional.py b/crazy_functional.py index ff4d81f2..cdfa921d 100644 --- a/crazy_functional.py +++ b/crazy_functional.py @@ -416,6 +416,19 @@ def get_crazy_functions(): except: print('Load function plugin failed') + try: + from crazy_functions.Three场景交互3D import 三维生成 + function_plugins.update({ + "ThreeJS 三维交互": { + "Color": "stop", + "AsButton": False, + "Function": HotReload(三维生成) + } + }) + except: + print('Load function plugin failed') + + # try: # from crazy_functions.虚空终端 import 终端 # function_plugins.update({ diff --git a/crazy_functions/Three场景交互3D.py b/crazy_functions/Three场景交互3D.py new file mode 100644 index 00000000..cf35ffd0 --- /dev/null +++ b/crazy_functions/Three场景交互3D.py @@ -0,0 +1,166 @@ +from toolbox import CatchException, update_ui, gen_time_str +from .crazy_utils import request_gpt_model_in_new_thread_with_ui_alive +from .crazy_utils import input_clipping + +def inspect_dependency(chatbot, history): + # 尝试导入依赖,如果缺少依赖,则给出安装建议 + try: + from VISUALIZE.mcom import mcom + return True + except: + chatbot.append(["导入依赖失败", "使用该模块需要额外依赖,安装方法:```pip install vhmap```"]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + return False + +def get_code_block(reply): + try: + import json + json.loads(reply) + return reply + except: + pass + + import re + pattern = r"```([\s\S]*?)```" # regex pattern to match code blocks + matches = re.findall(pattern, reply) # find all code blocks in text + res = "" + for match in matches: + if 'import ' not in match: + res = match.strip('python').strip('json') + break + if len(res) == 0: + print(reply) + raise RuntimeError("GPT is not generating proper Json.") + return res # code block + +def get_json_blocks(reply): + import re, json + pattern = r"{([\s\S]*?)}" # regex pattern to match code blocks + matches = re.findall(pattern, reply) # find all code blocks in text + res = [] + for match in matches: + if '"name"' in match: + try: + res.append(json.loads("{" + f'{match}' + "}")) + except: + pass + return res # code block + +def read_json(code): + import json + return json.loads(code) + +def parse_partial(vi, gpt_say): + # 解析Json + js = get_json_blocks(gpt_say) + vi.update(js) + + +@CatchException +def 三维生成(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): + """ + txt 输入栏用户输入的文本,例如需要翻译的一段话,再例如一个包含了待处理文件的路径 + llm_kwargs gpt模型参数,如温度和top_p等,一般原样传递下去就行 + plugin_kwargs 插件模型的参数,暂时没有用武之地 + chatbot 聊天显示框的句柄,用于显示给用户 + history 聊天历史,前情提要 + system_prompt 给gpt的静默提醒 + web_port 当前软件运行的端口号 + """ + from .vhmap_interact.vhmap import vhmp_interface + vi = vhmp_interface() + # 基本信息:功能、贡献者 + chatbot.append([ + "函数插件功能?", + "生成3D, 此插件处于开发阶段, 建议暂时不要使用, 作者: binary-husky, 插件初始化中 ..." + ]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 + + # 尝试导入依赖, 如果缺少依赖, 则给出安装建议 + dep_ok = yield from inspect_dependency(chatbot=chatbot, history=history) # 刷新界面 + if not dep_ok: return + + # 输入 + i_say = prompt(txt) + # 开始 + gpt_say = yield from request_gpt_model_in_new_thread_with_ui_alive( + inputs=i_say, inputs_show_user=i_say, + llm_kwargs=llm_kwargs, chatbot=chatbot, history=[], + sys_prompt=r"You are a Json generator", + on_reply_update=lambda t:parse_partial(vi, t) + ) + chatbot.append(["开始生成执行", "..."]) + history.extend([i_say, gpt_say]) + yield from update_ui(chatbot=chatbot, history=history) # 刷新界面 # 界面更新 + + # 解析Json + code = get_code_block(gpt_say) + js = read_json(code) + vi.update(js) + return + + +def prompt(text): + return r""" +> Requirements: + 1. You can only use square Boxes to build cubes and walls. + 2. The space you can work in is a sphere with origin (0,0,0) and radius 100. + 3. The ground is z=0. + 4. You can only use 100 boxes. + 5. Format of each box is json, e.g. + { + "name": "Box-1", + "geometry": "box", // choose from "box", "octahedron", "sphere", "cylinder" + "size": 1.0, + "color": "rgb(255,165,0)", + "location_x": 1.0, + "location_y": 0.0, + "location_z": 0.0 + }, + 6. Only produce json as output. Use markdown code block to wrap the json output. + +> Example: + User: Generate 4 different objects around the origin. + You: + ``` + [ + { + "name": "Box-1", + "size": 1.0, + "geometry": "box", + "color": "rgb(255,11,10)", + "location_x": 1.0, + "location_y": 0.0, + "location_z": 0.0 + }, + { + "name": "Box-2", + "size": 1.0, + "geometry": "octahedron", + "color": "rgb(255,11,10)", + "location_x": -1.0, + "location_y": 0.0, + "location_z": 0.0 + }, + { + "name": "Box-3", + "size": 1.0, + "geometry": "sphere", + "color": "rgb(255,11,10)", + "location_x": 0.0, + "location_y": 1.0, + "location_z": 0.0 + }, + { + "name": "Box-4", + "size": 1.0, + "geometry": "cylinder", + "color": "rgb(255,11,10)", + "location_x": 0.0, + "location_y": -1.0, + "location_z": 0.0 + } + ] + ``` + +> User: """ + text diff --git a/crazy_functions/crazy_functions_test.py b/crazy_functions/crazy_functions_test.py index 8b6b540e..ce4593fb 100644 --- a/crazy_functions/crazy_functions_test.py +++ b/crazy_functions/crazy_functions_test.py @@ -17,7 +17,7 @@ validate_path() # validate path so you can run from base directory # ============================================================================================================================== from colorful import * -from toolbox import get_conf, ChatBotWithCookies +from toolbox import get_conf, ChatBotWithCookies, load_chat_cookies import contextlib import os import sys @@ -32,6 +32,7 @@ llm_kwargs = { 'max_length': None, 'temperature':1.0, } +llm_kwargs.update(load_chat_cookies()) plugin_kwargs = { } chatbot = ChatBotWithCookies(llm_kwargs) history = [] @@ -226,6 +227,15 @@ def test_chatglm_finetune(): cli_printer.print(cb) +def 三维生成(): + from crazy_functions.Three场景交互3D import 三维生成 + txt = "Generate 10 boxes to form a triangle formation with random color." + plugin_kwargs = {"advanced_arg":""} + + for cookies, cb, hist, msg in (三维生成)(txt, llm_kwargs, plugin_kwargs, chatbot, history, system_prompt, web_port): + cli_printer.print(cb) + + if __name__ == "__main__": # test_解析一个Python项目() # test_Latex英文润色() @@ -241,6 +251,6 @@ if __name__ == "__main__": # test_Langchain知识库() # test_Langchain知识库读取() # test_Latex() - test_chatglm_finetune() + 三维生成() input("程序完成,回车退出。") print("退出。") \ No newline at end of file diff --git a/crazy_functions/crazy_utils.py b/crazy_functions/crazy_utils.py index ffe95e2b..b666c5d9 100644 --- a/crazy_functions/crazy_utils.py +++ b/crazy_functions/crazy_utils.py @@ -40,6 +40,7 @@ def request_gpt_model_in_new_thread_with_ui_alive( chatbot, history, sys_prompt, refresh_interval=0.2, handle_token_exceed=True, retry_times_at_unknown_error=2, + on_reply_update=None ): """ Request GPT model,请求GPT模型同时维持用户界面活跃。 @@ -123,6 +124,7 @@ def request_gpt_model_in_new_thread_with_ui_alive( if future.done(): break chatbot[-1] = [chatbot[-1][0], mutable[0]] + if on_reply_update: on_reply_update(mutable[0]) yield from update_ui(chatbot=chatbot, history=[]) # 刷新界面 final_result = future.result() diff --git a/crazy_functions/vhmap_interact/vhmap.py b/crazy_functions/vhmap_interact/vhmap.py new file mode 100644 index 00000000..4bbb2afb --- /dev/null +++ b/crazy_functions/vhmap_interact/vhmap.py @@ -0,0 +1,38 @@ +from toolbox import update_ui, get_conf, trimmed_format_exc +import threading + +def Singleton(cls): + _instance = {} + + def _singleton(*args, **kargs): + if cls not in _instance: + _instance[cls] = cls(*args, **kargs) + return _instance[cls] + + return _singleton + +@Singleton +class vhmp_interface(): + def __init__(self) -> None: + from VISUALIZE.mcom_rt import mcom + self.vis3d = mcom(path='TEMP/v2d_logger/', draw_mode='Threejs') + self.vis3d.v2d_init() + self.vis3d.设置样式('star') + # vis3d.设置样式('star') # 布置星空 + self.vis3d.其他几何体之旋转缩放和平移('box', 'BoxGeometry(1,1,1)', 0,0,0, 1,1,1, 0,0,0) + # declare geo 'oct1', init with OctahedronGeometry, then (1)rotate & (2)scale & (3)translate + self.vis3d.其他几何体之旋转缩放和平移('octahedron', 'OctahedronGeometry(1,0)', 0,0,0, 1,1,1, 0,0,0) # 八面体 + # 需要换成其他几何体,请把'OctahedronGeometry(1,0)'替换,参考网址 https://threejs.org/docs/index.html?q=Geometry + self.vis3d.其他几何体之旋转缩放和平移('sphere', 'SphereGeometry(1)', 0,0,0, 1,1,1, 0,0,0) # 球体 + self.vis3d.其他几何体之旋转缩放和平移('cylinder', 'CylinderGeometry(1,1,5,32)', 0,0,0, 1,1,1, 0,0,0) # 球体 + + def update(self, json): + for obj in json: + self.vis3d.发送几何体( + f'{obj["geometry"]}|{obj["name"]}|{obj["color"]}|{obj["size"]}', # 填入 ‘形状|几何体之ID标识|颜色|大小’即可 + obj["location_x"], + obj["location_y"], + obj["location_z"], + ro_x=0, ro_y=0, ro_z=0, # 三维位置+欧拉旋转变换,六自由度 + track_n_frame=0) # 显示历史20帧留下的轨迹 + self.vis3d.结束关键帧()