MichaelRKessler commited on
Commit
17afc32
·
1 Parent(s): f9e229a

Created a second tab as a placeholder for next part

Browse files
Files changed (1) hide show
  1. app.py +142 -134
app.py CHANGED
@@ -251,146 +251,154 @@ def shift_slice(state: ViewerState, index: float, delta: int) -> tuple[int, str,
251
 
252
 
253
  def build_demo() -> gr.Blocks:
254
- with gr.Blocks(title="STL TIFF Slicer") as demo:
255
- gr.Markdown(
256
- """
257
- # STL to TIFF Slicer
258
- Upload up to three STL files, choose a shared layer height and XY pixel size, then generate TIFF stacks for all uploaded models.
259
- """
260
- )
261
-
262
- with gr.Row():
263
- load_samples_button = gr.Button(
264
- "Load Sample STLs",
265
- variant="secondary",
266
- size="sm",
267
- min_width=140,
268
- scale=0,
269
  )
270
 
271
- # --- Upload + 3D viewer row ---
272
- stl_files: list[gr.File] = []
273
- model_viewers: list[gr.Model3D] = []
274
- model_details_list: list[gr.Markdown] = []
275
-
276
- with gr.Row():
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
  for i in range(3):
278
- with gr.Column(min_width=250):
279
- stl_file = gr.File(
280
- label=f"STL File {i + 1}",
281
- file_types=[".stl"],
282
- type="filepath",
283
- )
284
- model_viewer = gr.Model3D(
285
- label=f"3D Viewer {i + 1}",
286
- display_mode="solid",
287
- clear_color=(0.94, 0.95, 0.97, 1.0),
288
- height=270,
289
- )
290
- model_details = gr.Markdown(f"No model {i + 1} loaded.")
291
- stl_files.append(stl_file)
292
- model_viewers.append(model_viewer)
293
- model_details_list.append(model_details)
294
-
295
- # --- Shared slicing controls ---
296
- with gr.Row():
297
- layer_height = gr.Number(label="Layer Height", value=0.1, minimum=0.0001, step=0.01)
298
- pixel_size = gr.Number(label="Pixel Size", value=0.05, minimum=0.0001, step=0.01)
299
- generate_button = gr.Button("Generate TIFF Stacks", variant="primary")
300
-
301
- # --- Per-object slice browsers ---
302
- states: list[gr.State] = []
303
- sliders: list[gr.Slider] = []
304
- slice_labels: list[gr.Markdown] = []
305
- slice_previews: list[gr.Image] = []
306
- download_zips: list[gr.File] = []
307
-
308
- with gr.Row():
309
  for i in range(3):
310
- with gr.Column():
311
- slice_label = gr.Markdown("No slice stack loaded yet.")
312
- slice_preview = gr.Image(
313
- label=f"Slice Preview {i + 1}",
314
- type="pil",
315
- image_mode="L",
316
- height=324,
317
- )
318
- with gr.Row():
319
- prev_button = gr.Button("\u25c4 Prev")
320
- next_button = gr.Button("Next \u25ba")
321
- slice_slider = gr.Slider(
322
- label="Slice Index",
323
- minimum=0,
324
- maximum=0,
325
- value=0,
326
- step=1,
327
- interactive=False,
328
- )
329
- download_zip = gr.File(label=f"Download TIFF ZIP {i + 1}")
330
- state = gr.State(_empty_state())
331
-
332
- slice_labels.append(slice_label)
333
- slice_previews.append(slice_preview)
334
- sliders.append(slice_slider)
335
- download_zips.append(download_zip)
336
- states.append(state)
337
-
338
- slice_slider.release(
339
- fn=jump_to_slice,
340
- inputs=[state, slice_slider],
341
- outputs=[slice_label, slice_preview],
342
- queue=False,
343
- )
344
- prev_button.click(
345
- fn=lambda sv, idx: shift_slice(sv, idx, -1),
346
- inputs=[state, slice_slider],
347
- outputs=[slice_slider, slice_label, slice_preview],
348
- queue=False,
349
- )
350
- next_button.click(
351
- fn=lambda sv, idx: shift_slice(sv, idx, 1),
352
- inputs=[state, slice_slider],
353
- outputs=[slice_slider, slice_label, slice_preview],
354
- queue=False,
355
- )
356
-
357
- # --- File upload handlers ---
358
- for i in range(3):
359
- stl_files[i].change(
360
- fn=load_single_model,
361
- inputs=stl_files[i],
362
- outputs=[model_viewers[i], model_details_list[i]],
363
  )
364
 
365
- # --- Generate button ---
366
- generate_outputs: list = []
367
- for i in range(3):
368
- generate_outputs.extend([
369
- states[i],
370
- sliders[i],
371
- slice_labels[i],
372
- slice_previews[i],
373
- download_zips[i],
374
- ])
375
-
376
- preload_outputs: list = []
377
- for i in range(3):
378
- preload_outputs.extend([
379
- stl_files[i],
380
- model_viewers[i],
381
- model_details_list[i],
382
- ])
383
-
384
- load_samples_button.click(
385
- fn=preload_sample_models,
386
- outputs=preload_outputs,
387
- )
388
 
389
- generate_button.click(
390
- fn=generate_all_stacks,
391
- inputs=[stl_files[0], stl_files[1], stl_files[2], layer_height, pixel_size],
392
- outputs=generate_outputs,
393
- )
 
394
 
395
  return demo
396
 
@@ -399,4 +407,4 @@ demo = build_demo()
399
 
400
 
401
  if __name__ == "__main__":
402
- demo.launch(ssr_mode=False, css=APP_CSS, head=APP_HEAD)
 
251
 
252
 
253
  def build_demo() -> gr.Blocks:
254
+ with gr.Blocks(title="STL TIFF Slicer", css=APP_CSS, head=APP_HEAD) as demo:
255
+ with gr.Tab("STL to TIFF Slicer"):
256
+ gr.Markdown(
257
+ """
258
+ # STL to TIFF Slicer
259
+ Upload up to three STL files, choose a shared layer height and XY pixel size, then generate TIFF stacks for all uploaded models.
260
+ """
 
 
 
 
 
 
 
 
261
  )
262
 
263
+ with gr.Row():
264
+ load_samples_button = gr.Button(
265
+ "Load Sample STLs",
266
+ variant="secondary",
267
+ size="sm",
268
+ min_width=140,
269
+ scale=0,
270
+ )
271
+
272
+ # --- Upload + 3D viewer row ---
273
+ stl_files: list[gr.File] = []
274
+ model_viewers: list[gr.Model3D] = []
275
+ model_details_list: list[gr.Markdown] = []
276
+
277
+ with gr.Row():
278
+ for i in range(3):
279
+ with gr.Column(min_width=250):
280
+ stl_file = gr.File(
281
+ label=f"STL File {i + 1}",
282
+ file_types=[".stl"],
283
+ type="filepath",
284
+ )
285
+ model_viewer = gr.Model3D(
286
+ label=f"3D Viewer {i + 1}",
287
+ display_mode="solid",
288
+ clear_color=(0.94, 0.95, 0.97, 1.0),
289
+ height=270,
290
+ )
291
+ model_details = gr.Markdown(f"No model {i + 1} loaded.")
292
+ stl_files.append(stl_file)
293
+ model_viewers.append(model_viewer)
294
+ model_details_list.append(model_details)
295
+
296
+ # --- Shared slicing controls ---
297
+ with gr.Row():
298
+ layer_height = gr.Number(label="Layer Height", value=0.1, minimum=0.0001, step=0.01)
299
+ pixel_size = gr.Number(label="Pixel Size", value=0.05, minimum=0.0001, step=0.01)
300
+ generate_button = gr.Button("Generate TIFF Stacks", variant="primary")
301
+
302
+ # --- Per-object slice browsers ---
303
+ states: list[gr.State] = []
304
+ sliders: list[gr.Slider] = []
305
+ slice_labels: list[gr.Markdown] = []
306
+ slice_previews: list[gr.Image] = []
307
+ download_zips: list[gr.File] = []
308
+
309
+ with gr.Row():
310
+ for i in range(3):
311
+ with gr.Column(min_width=250):
312
+ slice_label = gr.Markdown("No slice stack loaded yet.")
313
+ slice_preview = gr.Image(
314
+ label=f"Slice Preview {i + 1}",
315
+ type="pil",
316
+ image_mode="L",
317
+ height=270,
318
+ )
319
+ with gr.Row():
320
+ prev_button = gr.Button("\u25c4 Prev", scale=1, min_width=90, size="sm")
321
+ next_button = gr.Button("Next \u25ba", scale=1, min_width=90, size="sm")
322
+ slice_slider = gr.Slider(
323
+ label="Slice Index",
324
+ minimum=0,
325
+ maximum=0,
326
+ value=0,
327
+ step=1,
328
+ interactive=False,
329
+ )
330
+ download_zip = gr.File(label=f"Download TIFF ZIP {i + 1}")
331
+ state = gr.State(_empty_state())
332
+
333
+ slice_labels.append(slice_label)
334
+ slice_previews.append(slice_preview)
335
+ sliders.append(slice_slider)
336
+ download_zips.append(download_zip)
337
+ states.append(state)
338
+
339
+ slice_slider.release(
340
+ fn=jump_to_slice,
341
+ inputs=[state, slice_slider],
342
+ outputs=[slice_label, slice_preview],
343
+ queue=False,
344
+ )
345
+ prev_button.click(
346
+ fn=lambda sv, idx: shift_slice(sv, idx, -1),
347
+ inputs=[state, slice_slider],
348
+ outputs=[slice_slider, slice_label, slice_preview],
349
+ queue=False,
350
+ )
351
+ next_button.click(
352
+ fn=lambda sv, idx: shift_slice(sv, idx, 1),
353
+ inputs=[state, slice_slider],
354
+ outputs=[slice_slider, slice_label, slice_preview],
355
+ queue=False,
356
+ )
357
+
358
+ # --- File upload handlers ---
359
  for i in range(3):
360
+ stl_files[i].change(
361
+ fn=load_single_model,
362
+ inputs=stl_files[i],
363
+ outputs=[model_viewers[i], model_details_list[i]],
364
+ )
365
+
366
+ # --- Generate button ---
367
+ generate_outputs: list = []
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
368
  for i in range(3):
369
+ generate_outputs.extend([
370
+ states[i],
371
+ sliders[i],
372
+ slice_labels[i],
373
+ slice_previews[i],
374
+ download_zips[i],
375
+ ])
376
+
377
+ preload_outputs: list = []
378
+ for i in range(3):
379
+ preload_outputs.extend([
380
+ stl_files[i],
381
+ model_viewers[i],
382
+ model_details_list[i],
383
+ ])
384
+
385
+ load_samples_button.click(
386
+ fn=preload_sample_models,
387
+ outputs=preload_outputs,
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
388
  )
389
 
390
+ generate_button.click(
391
+ fn=generate_all_stacks,
392
+ inputs=[stl_files[0], stl_files[1], stl_files[2], layer_height, pixel_size],
393
+ outputs=generate_outputs,
394
+ )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
 
396
+ with gr.Tab("TIFF Slices to GCode"):
397
+ gr.Textbox(
398
+ label="Status",
399
+ value="More to come later.",
400
+ interactive=False,
401
+ )
402
 
403
  return demo
404
 
 
407
 
408
 
409
  if __name__ == "__main__":
410
+ demo.launch(ssr_mode=False)