TruthLens commited on
Commit
1277ccd
·
verified ·
1 Parent(s): ab2c761

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +51 -46
app.py CHANGED
@@ -2,9 +2,10 @@ import os
2
  import numpy as np
3
  from PIL import Image
4
  from stl import mesh
5
- import plotly.graph_objects as go
6
  from flask import Flask, render_template_string, request, send_file
7
  from werkzeug.utils import secure_filename
 
 
8
 
9
  app = Flask(__name__)
10
  UPLOAD_FOLDER = 'uploads'
@@ -19,7 +20,7 @@ HTML_TEMPLATE = """
19
  <html lang="en">
20
  <head>
21
  <meta charset="UTF-8">
22
- <title>3D Model Generator for 3D Printing</title>
23
  </head>
24
  <body>
25
  <h1>Upload Image to Generate 3D Printable Model</h1>
@@ -27,67 +28,71 @@ HTML_TEMPLATE = """
27
  <label>Image:</label><input type="file" name="image" required><br><br>
28
  <input type="submit" value="Upload & Generate 3D Model">
29
  </form>
30
- {% if plot_div %}
31
- <h2>3D Model Preview:</h2>
32
- {{ plot_div|safe }}
33
- <br>
34
  <a href="{{ download_link }}" download>Download STL File</a>
35
  {% endif %}
36
  </body>
37
  </html>
38
  """
39
 
40
- def generate_3d_model(image_path, output_stl_path, scale=1.0, height_scale=5.0):
41
- image = Image.open(image_path).convert('L')
42
- img_array = np.array(image)
43
-
44
- height, width = img_array.shape
45
- x, y = np.meshgrid(np.linspace(0, width * scale, width), np.linspace(0, height * scale, height))
46
- z = (img_array / 255.0) * height_scale
47
 
48
- # Create vertices and faces
49
- vertices = np.column_stack((x.flatten(), y.flatten(), z.flatten()))
 
50
  faces = []
51
- for i in range(height - 1):
52
- for j in range(width - 1):
53
- idx = i * width + j
54
- faces.append([idx, idx + 1, idx + width])
55
- faces.append([idx + 1, idx + width + 1, idx + width])
56
-
57
- # Create STL mesh
58
- model_mesh = mesh.Mesh(np.zeros(len(faces), dtype=mesh.Mesh.dtype))
59
- for i, f in enumerate(faces):
60
- for j in range(3):
61
- model_mesh.vectors[i][j] = vertices[f[j], :]
62
-
63
- model_mesh.save(output_stl_path)
64
-
65
- fig = go.Figure(data=[go.Surface(z=z, x=x, y=y, colorscale='Gray')])
66
- fig.update_layout(scene=dict(aspectratio=dict(x=1, y=1, z=0.3)), margin=dict(l=0, r=0, b=0, t=0))
67
-
68
- return fig.to_html(full_html=False)
 
 
 
 
 
 
 
 
 
69
 
70
  @app.route('/', methods=['GET'])
71
  def index():
72
- return render_template_string(HTML_TEMPLATE, plot_div=None, download_link=None)
73
 
74
  @app.route('/upload', methods=['POST'])
75
  def upload():
76
- image = request.files['image']
77
- image_path = os.path.join(app.config['UPLOAD_FOLDER'], secure_filename(image.filename))
78
- image.save(image_path)
79
-
80
- stl_filename = os.path.splitext(image.filename)[0] + '.stl'
81
- output_stl_path = os.path.join(app.config['OUTPUT_FOLDER'], stl_filename)
82
-
83
- plot_div = generate_3d_model(image_path, output_stl_path)
84
- download_link = f"/download/{stl_filename}"
85
 
86
- return render_template_string(HTML_TEMPLATE, plot_div=plot_div, download_link=download_link)
 
 
87
 
88
- @app.route('/download/<filename>')
89
  def download_file(filename):
90
  return send_file(os.path.join(app.config['OUTPUT_FOLDER'], filename), as_attachment=True)
91
 
92
  if __name__ == '__main__':
93
- app.run(debug=True)
 
2
  import numpy as np
3
  from PIL import Image
4
  from stl import mesh
 
5
  from flask import Flask, render_template_string, request, send_file
6
  from werkzeug.utils import secure_filename
7
+ from io import BytesIO
8
+ import cv2
9
 
10
  app = Flask(__name__)
11
  UPLOAD_FOLDER = 'uploads'
 
20
  <html lang="en">
21
  <head>
22
  <meta charset="UTF-8">
23
+ <title>3D Printing Model Generator</title>
24
  </head>
25
  <body>
26
  <h1>Upload Image to Generate 3D Printable Model</h1>
 
28
  <label>Image:</label><input type="file" name="image" required><br><br>
29
  <input type="submit" value="Upload & Generate 3D Model">
30
  </form>
31
+ {% if download_link %}
32
+ <h2>3D Model Ready:</h2>
 
 
33
  <a href="{{ download_link }}" download>Download STL File</a>
34
  {% endif %}
35
  </body>
36
  </html>
37
  """
38
 
39
+ def image_to_height_map(image_path, size=(256, 256)):
40
+ image = cv2.imread(image_path, cv2.IMREAD_GRAYSCALE)
41
+ resized = cv2.resize(image, size)
42
+ normalized = resized / 255.0
43
+ return normalized
 
 
44
 
45
+ def height_map_to_stl(height_map, output_path, scale=10.0):
46
+ rows, cols = height_map.shape
47
+ vertices = []
48
  faces = []
49
+
50
+ for i in range(rows):
51
+ for j in range(cols):
52
+ z = height_map[i, j] * scale
53
+ vertices.append([j, i, z])
54
+
55
+ vertices = np.array(vertices).reshape((rows, cols, 3))
56
+ face_list = []
57
+
58
+ for i in range(rows - 1):
59
+ for j in range(cols - 1):
60
+ face_list.append([vertices[i, j], vertices[i + 1, j], vertices[i, j + 1]])
61
+ face_list.append([vertices[i + 1, j], vertices[i + 1, j + 1], vertices[i, j + 1]])
62
+
63
+ faces_np = np.array(face_list)
64
+ model = mesh.Mesh(np.zeros(faces_np.shape[0], dtype=mesh.Mesh.dtype))
65
+
66
+ for i, f in enumerate(faces_np):
67
+ model.vectors[i] = f
68
+
69
+ model.save(output_path)
70
+
71
+ def create_3d_model(image_path):
72
+ height_map = image_to_height_map(image_path)
73
+ output_path = os.path.join(app.config['OUTPUT_FOLDER'], 'model.stl')
74
+ height_map_to_stl(height_map, output_path)
75
+ return output_path
76
 
77
  @app.route('/', methods=['GET'])
78
  def index():
79
+ return render_template_string(HTML_TEMPLATE, download_link=None)
80
 
81
  @app.route('/upload', methods=['POST'])
82
  def upload():
83
+ uploaded_file = request.files['image']
84
+ if uploaded_file:
85
+ filename = secure_filename(uploaded_file.filename)
86
+ image_path = os.path.join(app.config['UPLOAD_FOLDER'], filename)
87
+ uploaded_file.save(image_path)
 
 
 
 
88
 
89
+ stl_path = create_3d_model(image_path)
90
+ return render_template_string(HTML_TEMPLATE, download_link=f'/download/{os.path.basename(stl_path)}')
91
+ return render_template_string(HTML_TEMPLATE, download_link=None)
92
 
93
+ @app.route('/download/<filename>', methods=['GET'])
94
  def download_file(filename):
95
  return send_file(os.path.join(app.config['OUTPUT_FOLDER'], filename), as_attachment=True)
96
 
97
  if __name__ == '__main__':
98
+ app.run(debug=True, host='0.0.0.0', port=5000)