Spaces:
Running
Running
Commit ·
c315fc4
1
Parent(s): e237055
feat: expand slicing and gcode workflow UI
Browse files
app.py
CHANGED
|
@@ -11,7 +11,7 @@ from tiff_to_gcode import generate_snake_path_gcode
|
|
| 11 |
|
| 12 |
|
| 13 |
ViewerState = dict[str, Any]
|
| 14 |
-
SAMPLE_STL_FILENAMES = ("Hollow_Pyramid.stl", "
|
| 15 |
SAMPLE_STL_DIR = Path(__file__).resolve().parent / "sample_stls"
|
| 16 |
APP_CSS = """
|
| 17 |
.gradio-container {
|
|
@@ -105,7 +105,21 @@ APP_HEAD = """
|
|
| 105 |
|
| 106 |
def _read_slice_preview(path: str) -> Image.Image:
|
| 107 |
with Image.open(path) as image:
|
| 108 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 109 |
|
| 110 |
|
| 111 |
def _empty_state() -> ViewerState:
|
|
@@ -272,6 +286,7 @@ def run_all_tiff_to_gcode(
|
|
| 272 |
pressure3: float,
|
| 273 |
valve3: float,
|
| 274 |
port3: float,
|
|
|
|
| 275 |
) -> tuple[str | None, str | None, str | None, str]:
|
| 276 |
specs = [
|
| 277 |
(1, zip1, pressure1, valve1, port1),
|
|
@@ -298,6 +313,7 @@ def run_all_tiff_to_gcode(
|
|
| 298 |
pressure=float(pressure),
|
| 299 |
valve=int(valve),
|
| 300 |
port=int(port),
|
|
|
|
| 301 |
)
|
| 302 |
outputs[idx - 1] = str(gcode_path)
|
| 303 |
messages.append(f"Shape {idx}: wrote `{gcode_path.name}`.")
|
|
@@ -363,8 +379,8 @@ def build_demo() -> gr.Blocks:
|
|
| 363 |
|
| 364 |
# --- Shared slicing controls ---
|
| 365 |
with gr.Row():
|
| 366 |
-
layer_height = gr.Number(label="Layer Height", value=0.
|
| 367 |
-
pixel_size = gr.Number(label="Pixel Size", value=0.
|
| 368 |
generate_button = gr.Button("Generate TIFF Stacks", variant="primary")
|
| 369 |
|
| 370 |
# --- Per-object slice browsers ---
|
|
@@ -586,6 +602,7 @@ def build_demo() -> gr.Blocks:
|
|
| 586 |
gcode_pressure_3,
|
| 587 |
gcode_valve_3,
|
| 588 |
gcode_port_3,
|
|
|
|
| 589 |
],
|
| 590 |
outputs=[gcode_file_1, gcode_file_2, gcode_file_3, gcode_status],
|
| 591 |
)
|
|
|
|
| 11 |
|
| 12 |
|
| 13 |
ViewerState = dict[str, Any]
|
| 14 |
+
SAMPLE_STL_FILENAMES = ("Hollow_Pyramid.stl", "Rounded_Cube_Through_Holes.stl", "halfsphere.stl")
|
| 15 |
SAMPLE_STL_DIR = Path(__file__).resolve().parent / "sample_stls"
|
| 16 |
APP_CSS = """
|
| 17 |
.gradio-container {
|
|
|
|
| 105 |
|
| 106 |
def _read_slice_preview(path: str) -> Image.Image:
|
| 107 |
with Image.open(path) as image:
|
| 108 |
+
preview = image.copy()
|
| 109 |
+
|
| 110 |
+
# Upscale low-resolution TIFF previews so they fill the viewer area better.
|
| 111 |
+
min_display_side = 480
|
| 112 |
+
width, height = preview.size
|
| 113 |
+
max_dim = max(width, height)
|
| 114 |
+
if max_dim > 0 and max_dim < min_display_side:
|
| 115 |
+
scale = min_display_side / max_dim
|
| 116 |
+
new_size = (
|
| 117 |
+
max(1, int(round(width * scale))),
|
| 118 |
+
max(1, int(round(height * scale))),
|
| 119 |
+
)
|
| 120 |
+
preview = preview.resize(new_size, resample=Image.Resampling.NEAREST)
|
| 121 |
+
|
| 122 |
+
return preview
|
| 123 |
|
| 124 |
|
| 125 |
def _empty_state() -> ViewerState:
|
|
|
|
| 286 |
pressure3: float,
|
| 287 |
valve3: float,
|
| 288 |
port3: float,
|
| 289 |
+
layer_height: float = 0.8,
|
| 290 |
) -> tuple[str | None, str | None, str | None, str]:
|
| 291 |
specs = [
|
| 292 |
(1, zip1, pressure1, valve1, port1),
|
|
|
|
| 313 |
pressure=float(pressure),
|
| 314 |
valve=int(valve),
|
| 315 |
port=int(port),
|
| 316 |
+
layer_height=float(layer_height),
|
| 317 |
)
|
| 318 |
outputs[idx - 1] = str(gcode_path)
|
| 319 |
messages.append(f"Shape {idx}: wrote `{gcode_path.name}`.")
|
|
|
|
| 379 |
|
| 380 |
# --- Shared slicing controls ---
|
| 381 |
with gr.Row():
|
| 382 |
+
layer_height = gr.Number(label="Layer Height", value=0.8, minimum=0.0001, step=0.01)
|
| 383 |
+
pixel_size = gr.Number(label="Pixel Size", value=0.8, minimum=0.0001, step=0.01)
|
| 384 |
generate_button = gr.Button("Generate TIFF Stacks", variant="primary")
|
| 385 |
|
| 386 |
# --- Per-object slice browsers ---
|
|
|
|
| 602 |
gcode_pressure_3,
|
| 603 |
gcode_valve_3,
|
| 604 |
gcode_port_3,
|
| 605 |
+
layer_height,
|
| 606 |
],
|
| 607 |
outputs=[gcode_file_1, gcode_file_2, gcode_file_3, gcode_status],
|
| 608 |
)
|
sample_stls/{balanced_die.stl → Rounded_Cube_Through_Holes.stl}
RENAMED
|
@@ -1,3 +1,3 @@
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
-
oid sha256:
|
| 3 |
-
size
|
|
|
|
| 1 |
version https://git-lfs.github.com/spec/v1
|
| 2 |
+
oid sha256:e0d8a159cc44350ea75c63699960216a7f097ccd2321698918c1bd5bace49510
|
| 3 |
+
size 2299409
|
tiff_to_gcode.py
CHANGED
|
@@ -169,6 +169,7 @@ def generate_snake_path_gcode(
|
|
| 169 |
pressure: float,
|
| 170 |
valve: int,
|
| 171 |
port: int,
|
|
|
|
| 172 |
fil_width: float = 0.8,
|
| 173 |
invert: bool = True,
|
| 174 |
increase_pressure_per_layer: float = 0.1,
|
|
@@ -256,7 +257,7 @@ def generate_snake_path_gcode(
|
|
| 256 |
|
| 257 |
if layers > 0:
|
| 258 |
gcode_list.append(
|
| 259 |
-
{"X": shift_y, "Y": shift_x, "Z":
|
| 260 |
)
|
| 261 |
|
| 262 |
for row in current_image_ref:
|
|
@@ -308,7 +309,7 @@ def generate_snake_path_gcode(
|
|
| 308 |
move_type = "G0" if cur_color != off_color else "G1"
|
| 309 |
if "Z" in move:
|
| 310 |
line = (
|
| 311 |
-
f"{move_type} X{move['X']} Y{move['Y']} Z{
|
| 312 |
f"; Color {move['Color']}"
|
| 313 |
)
|
| 314 |
pressure_cur += increase_pressure_per_layer
|
|
|
|
| 169 |
pressure: float,
|
| 170 |
valve: int,
|
| 171 |
port: int,
|
| 172 |
+
layer_height: float = 0.8,
|
| 173 |
fil_width: float = 0.8,
|
| 174 |
invert: bool = True,
|
| 175 |
increase_pressure_per_layer: float = 0.1,
|
|
|
|
| 257 |
|
| 258 |
if layers > 0:
|
| 259 |
gcode_list.append(
|
| 260 |
+
{"X": shift_y, "Y": shift_x, "Z": layer_height, "Color": 0}
|
| 261 |
)
|
| 262 |
|
| 263 |
for row in current_image_ref:
|
|
|
|
| 309 |
move_type = "G0" if cur_color != off_color else "G1"
|
| 310 |
if "Z" in move:
|
| 311 |
line = (
|
| 312 |
+
f"{move_type} X{move['X']} Y{move['Y']} Z{move['Z']} "
|
| 313 |
f"; Color {move['Color']}"
|
| 314 |
)
|
| 315 |
pressure_cur += increase_pressure_per_layer
|