| import streamlit as st |
| from transformers import AutoTokenizer, AutoModelForCausalLM, TextIteratorStreamer |
| import google.generativeai as genai |
| from threading import Thread |
| import trimesh |
| import numpy as np |
| import tempfile |
| import os |
|
|
| |
| genai.configure(api_key=st.secrets["GOOGLE_API_KEY"]) |
|
|
| |
| os.environ["HF_TOKEN"] = st.secrets["HF_TOKEN"] |
|
|
| |
| model_path = "Zhengyi/LLaMA-Mesh" |
| tokenizer = AutoTokenizer.from_pretrained(model_path) |
| model = AutoModelForCausalLM.from_pretrained(model_path, device_map="auto", low_cpu_mem_usage=True) |
| terminators = [tokenizer.eos_token_id, tokenizer.convert_tokens_to_ids("<|eot_id|>")] |
|
|
| def generate_mesh(prompt, temperature=0.9, max_new_tokens=4096): |
| conversation = [{"role": "user", "content": prompt}] |
| input_ids = tokenizer.apply_chat_template(conversation, return_tensors="pt").to(model.device) |
|
|
| streamer = TextIteratorStreamer(tokenizer, timeout=10.0, skip_prompt=True, skip_special_tokens=True) |
| generate_kwargs = dict( |
| input_ids=input_ids, |
| streamer=streamer, |
| max_new_tokens=max_new_tokens, |
| do_sample=True, |
| temperature=temperature, |
| eos_token_id=terminators, |
| ) |
|
|
| if temperature == 0: |
| generate_kwargs['do_sample'] = False |
|
|
| t = Thread(target=model.generate, kwargs=generate_kwargs) |
| t.start() |
|
|
| outputs = [] |
| for text in streamer: |
| outputs.append(text) |
| return "".join(outputs) |
|
|
| def apply_gradient_color(mesh_text): |
| temp_file = tempfile.NamedTemporaryFile(suffix="", delete=False).name |
| with open(temp_file + ".obj", "w") as f: |
| f.write(mesh_text) |
| mesh = trimesh.load_mesh(temp_file + ".obj", file_type='obj') |
|
|
| vertices = mesh.vertices |
| y_values = vertices[:, 1] |
|
|
| y_normalized = (y_values - y_values.min()) / (y_values.max() - y_values.min()) |
|
|
| colors = np.zeros((len(vertices), 4)) |
| colors[:, 0] = y_normalized |
| colors[:, 2] = 1 - y_normalized |
| colors[:, 3] = 1.0 |
|
|
| mesh.visual.vertex_colors = colors |
|
|
| glb_path = temp_file + ".glb" |
| with open(glb_path, "wb") as f: |
| f.write(trimesh.exchange.gltf.export_glb(mesh)) |
| return glb_path |
|
|
| |
| st.title("Ever AI - 3D CAD Model Generator") |
| st.write("Use generative AI to create 3D CAD models based on your prompt.") |
|
|
| prompt = st.text_input("Enter your prompt:", "Create a 3D model of a house.") |
|
|
| if st.button("Generate CAD Model"): |
| try: |
| response = generate_mesh(prompt) |
| |
| cad_file_path = "generated_model.obj" |
| with open(cad_file_path, "w") as f: |
| f.write(response) |
| |
| st.write("CAD Model Generated:") |
| st.code(response, language='plaintext') |
|
|
| glb_path = apply_gradient_color(response) |
| with open(glb_path, "rb") as f: |
| btn = st.download_button( |
| label="Download GLB File", |
| data=f, |
| file_name="generated_model.glb", |
| mime="application/octet-stream" |
| ) |
| except Exception as e: |
| st.error(f"Error: {e}") |