Spaces:
Runtime error
Runtime error
setting up the generation and processing of images and 3d assets
Browse files- get_blender.py +0 -63
- main.py +62 -0
- setup.sh +0 -20
- utils.py +44 -0
- vision_model.py +84 -0
get_blender.py
DELETED
@@ -1,63 +0,0 @@
|
|
1 |
-
import os
|
2 |
-
import shutil
|
3 |
-
import subprocess
|
4 |
-
import sys
|
5 |
-
import tarfile
|
6 |
-
import urllib.request
|
7 |
-
|
8 |
-
def download_blender(url, destination):
|
9 |
-
urllib.request.urlretrieve(url, destination)
|
10 |
-
|
11 |
-
def extract_archive(archive_file, destination):
|
12 |
-
with tarfile.open(archive_file, 'r:xz') as tar:
|
13 |
-
tar.extractall(destination)
|
14 |
-
|
15 |
-
def remove_file(file_path):
|
16 |
-
os.remove(file_path)
|
17 |
-
|
18 |
-
def move_folder(source, destination):
|
19 |
-
shutil.move(source, destination)
|
20 |
-
|
21 |
-
def create_symbolic_link(source, target):
|
22 |
-
os.symlink(source, target)
|
23 |
-
|
24 |
-
def install_packages(packages):
|
25 |
-
subprocess.run(['sudo', 'apt-get', 'update'])
|
26 |
-
subprocess.run(['sudo', 'apt-get', 'install'] + packages + ['-y'])
|
27 |
-
|
28 |
-
def main():
|
29 |
-
blender_url = 'https://download.blender.org/release/Blender4.0/blender-4.0.2-linux-x64.tar.xz'
|
30 |
-
archive_file = 'blender-4.0.2-linux-x64.tar.xz'
|
31 |
-
extracted_folder = 'blender-4.0.2-linux-x64'
|
32 |
-
destination_folder = '/opt/blender-4.0.2'
|
33 |
-
symbolic_link = '/usr/local/bin/blender'
|
34 |
-
packages_to_install = ['libxxf86vm1', 'libgl1-mesa-glx', 'libegl-mesa0', 'libegl1']
|
35 |
-
|
36 |
-
# Download Blender
|
37 |
-
print("Downloading Blender...")
|
38 |
-
download_blender(blender_url, archive_file)
|
39 |
-
|
40 |
-
# Extract the downloaded archive
|
41 |
-
print("Extracting Blender archive...")
|
42 |
-
extract_archive(archive_file, '.')
|
43 |
-
|
44 |
-
# Remove the downloaded archive
|
45 |
-
print("Removing downloaded archive...")
|
46 |
-
remove_file(archive_file)
|
47 |
-
|
48 |
-
# Move the extracted folder to the desired location
|
49 |
-
print("Moving Blender folder...")
|
50 |
-
move_folder(extracted_folder, destination_folder)
|
51 |
-
|
52 |
-
# Create a symbolic link to the Blender executable
|
53 |
-
print("Creating symbolic link to Blender executable...")
|
54 |
-
create_symbolic_link(os.path.join(destination_folder, 'blender'), symbolic_link)
|
55 |
-
|
56 |
-
# Install required packages
|
57 |
-
print("Installing required packages...")
|
58 |
-
install_packages(packages_to_install)
|
59 |
-
|
60 |
-
print("Installation complete.")
|
61 |
-
|
62 |
-
if __name__ == "__main__":
|
63 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
main.py
ADDED
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from langhchain_generate_components import maker_wikipedia_chain
|
2 |
+
from utils import (
|
3 |
+
save_file, convert_obj_to_stl,
|
4 |
+
change_file_extension,
|
5 |
+
)
|
6 |
+
from mesh_utils import generate_mesh_images
|
7 |
+
from gradio_client import Client
|
8 |
+
|
9 |
+
|
10 |
+
def main():
|
11 |
+
# the object to be generated
|
12 |
+
query = "A Microscope"
|
13 |
+
|
14 |
+
# using a retriever we generat a list of Components
|
15 |
+
output = maker_wikipedia_chain.invoke(query)
|
16 |
+
|
17 |
+
# the first item
|
18 |
+
shap_e_sample = output['Material'][0]
|
19 |
+
|
20 |
+
client = Client("hysts/Shap-E")
|
21 |
+
result = client.predict(
|
22 |
+
shap_e_sample, # str in 'Prompt' Textbox component
|
23 |
+
1621396601, # float (numeric value between 0 and 2147483647) in 'Seed' Slider component
|
24 |
+
15, # float (numeric value between 1 and 20) in 'Guidance scale' Slider component
|
25 |
+
64, # float (numeric value between 2 and 100) in 'Number of inference steps' Slider component
|
26 |
+
api_name="/text-to-3d"
|
27 |
+
)
|
28 |
+
|
29 |
+
saved_file_name = "sample.glb"
|
30 |
+
# save to local machine
|
31 |
+
save_file(result,saved_file_name)
|
32 |
+
|
33 |
+
stl_file_location = change_file_extension(
|
34 |
+
saved_file_name,
|
35 |
+
".stl"
|
36 |
+
)
|
37 |
+
|
38 |
+
# convert into a stl without the texture
|
39 |
+
# as it is easiest to handle
|
40 |
+
convert_obj_to_stl(
|
41 |
+
result,
|
42 |
+
stl_file_location,
|
43 |
+
)
|
44 |
+
|
45 |
+
# Need to generate screenshot for the item
|
46 |
+
|
47 |
+
viewing_angles = [(30, 45), (60, 90), (45, 135)]
|
48 |
+
|
49 |
+
generate_mesh_images(
|
50 |
+
stl_file_location,
|
51 |
+
viewing_angles
|
52 |
+
)
|
53 |
+
|
54 |
+
# These screenshots need to be given to GPT-V
|
55 |
+
# for feedback
|
56 |
+
|
57 |
+
print(result)
|
58 |
+
|
59 |
+
x = 0
|
60 |
+
|
61 |
+
if __name__ == "__main__":
|
62 |
+
main()
|
setup.sh
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
# download belnder
|
2 |
-
wget https://download.blender.org/release/Blender4.0/blender-4.0.2-linux-x64.tar.xz
|
3 |
-
|
4 |
-
# Extract the downloaded archive:
|
5 |
-
|
6 |
-
tar xf blender-4.0.2-linux-x64.tar.xz
|
7 |
-
|
8 |
-
rm -fr blender-4.0.2-linux-x64.tar.xz
|
9 |
-
|
10 |
-
# Move the extracted folder to the desired location (for example, /opt):
|
11 |
-
sudo mv blender-4.0.2-linux-x64 /opt/blender-4.0.2
|
12 |
-
|
13 |
-
# Create a symbolic link to the Blender executable:
|
14 |
-
sudo ln -s /opt/blender-4.0.2/blender /usr/local/bin/blender
|
15 |
-
|
16 |
-
sudo apt-get update
|
17 |
-
sudo apt-get install libxxf86vm1 -y
|
18 |
-
sudo apt-get install libgl1-mesa-glx -y
|
19 |
-
sudo apt-get install libegl-mesa0 -y
|
20 |
-
sudo apt-get install libegl1 -y
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
utils.py
ADDED
@@ -0,0 +1,44 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import shutil
|
2 |
+
import trimesh
|
3 |
+
import os
|
4 |
+
|
5 |
+
def save_file(input_file, output_file):
|
6 |
+
"""
|
7 |
+
Copy a file from input location to output location.
|
8 |
+
|
9 |
+
Args:
|
10 |
+
input_file (str): Path to the input file.
|
11 |
+
output_file (str): Path to the output file.
|
12 |
+
|
13 |
+
Returns:
|
14 |
+
bool: True if the file is successfully saved, False otherwise.
|
15 |
+
"""
|
16 |
+
try:
|
17 |
+
shutil.copy(input_file, output_file)
|
18 |
+
return True
|
19 |
+
except Exception as e:
|
20 |
+
print(f"Error: {e}")
|
21 |
+
return False
|
22 |
+
|
23 |
+
|
24 |
+
def convert_obj_to_stl(input_file: str, output_file: str):
|
25 |
+
# Load the OBJ file
|
26 |
+
mesh = trimesh.load(input_file)
|
27 |
+
|
28 |
+
# Export as STL
|
29 |
+
mesh.export(output_file)
|
30 |
+
|
31 |
+
def change_file_extension(file_path: str, new_extension: str) -> str:
|
32 |
+
"""
|
33 |
+
Change the extension of a file path.
|
34 |
+
|
35 |
+
Args:
|
36 |
+
file_path (str): The original file path.
|
37 |
+
new_extension (str): The new file extension (without the dot).
|
38 |
+
|
39 |
+
Returns:
|
40 |
+
str: The modified file path with the new extension.
|
41 |
+
"""
|
42 |
+
base_path, _ = os.path.splitext(file_path)
|
43 |
+
new_file_path = base_path + '.' + new_extension
|
44 |
+
return new_file_path
|
vision_model.py
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import base64
|
2 |
+
from openai import OpenAI
|
3 |
+
from typing import List, Dict, Any
|
4 |
+
from dotenv import load_dotenv
|
5 |
+
import os
|
6 |
+
|
7 |
+
load_dotenv()
|
8 |
+
|
9 |
+
# source
|
10 |
+
# https://platform.openai.com/docs/guides/vision?lang=python
|
11 |
+
def analyze_images(
|
12 |
+
images: List[str],
|
13 |
+
prompt: str,
|
14 |
+
# api_key: str,
|
15 |
+
model: str = "gpt-4-vision-preview",
|
16 |
+
max_tokens: int = 300
|
17 |
+
) -> Dict[str, Any]:
|
18 |
+
"""
|
19 |
+
Analyze multiple images using OpenAI's vision model.
|
20 |
+
|
21 |
+
Args:
|
22 |
+
images (List[str]): List of URLs and/or local paths to the image files.
|
23 |
+
prompt (str): Prompt message for the AI model.
|
24 |
+
api_key (str): Your OpenAI API key.
|
25 |
+
model (str, optional): Name of the vision model to use. Defaults to "gpt-4-vision-preview".
|
26 |
+
max_tokens (int, optional): Maximum number of tokens for the response. Defaults to 300.
|
27 |
+
|
28 |
+
Returns:
|
29 |
+
dict: JSON response from the API.
|
30 |
+
"""
|
31 |
+
client = OpenAI()
|
32 |
+
messages = [{
|
33 |
+
"role": "user",
|
34 |
+
"content": [{"type": "text", "text": prompt}]
|
35 |
+
}]
|
36 |
+
|
37 |
+
for image in images:
|
38 |
+
if image.startswith("http://") or image.startswith("https://"):
|
39 |
+
# Image is a URL
|
40 |
+
messages.append({
|
41 |
+
"role": "user",
|
42 |
+
"content": [{"type": "image_url", "image_url": {"url": image}}]
|
43 |
+
})
|
44 |
+
else:
|
45 |
+
# Image is a local path
|
46 |
+
with open(image, "rb") as image_file:
|
47 |
+
base64_image = base64.b64encode(image_file.read()).decode('utf-8')
|
48 |
+
messages.append({
|
49 |
+
"role": "user",
|
50 |
+
"content": [{"type": "image_url", "image_url": {"url": f"data:image/jpeg;base64,{base64_image}"}}]
|
51 |
+
})
|
52 |
+
|
53 |
+
response = client.chat.completions.create(
|
54 |
+
model=model,
|
55 |
+
messages=messages,
|
56 |
+
max_tokens=max_tokens
|
57 |
+
)
|
58 |
+
return response.choices[0]
|
59 |
+
|
60 |
+
def main():
|
61 |
+
api_key = os.getenv("OPENAI_API_KEY")
|
62 |
+
images = [
|
63 |
+
"/workspaces/Maker-Tech-Tree/mesh_1.png",
|
64 |
+
"/workspaces/Maker-Tech-Tree/mesh_2.png",
|
65 |
+
"/workspaces/Maker-Tech-Tree/mesh_3.png",
|
66 |
+
]
|
67 |
+
prompt = "I am creating an 3d model of a Glass lenses for refracting light,\
|
68 |
+
using a text-to-3d model\
|
69 |
+
Do these images look correct?\
|
70 |
+
If not please make a suggesttion on how to improve the text input\
|
71 |
+
As this response will be used in a pipeline please only output a new \
|
72 |
+
potential prompt or output nothing, \
|
73 |
+
Please keep the prompt to 5 25 words to not confuse the model"
|
74 |
+
|
75 |
+
response = analyze_images(
|
76 |
+
images,
|
77 |
+
prompt,
|
78 |
+
# api_key,
|
79 |
+
)
|
80 |
+
|
81 |
+
print(response)
|
82 |
+
|
83 |
+
if __name__ == "__main__":
|
84 |
+
main()
|