unveil-python 0.1.0__tar.gz → 0.2.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unveil-python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Implementation of UNVEIL
5
5
  Author-email: Nicolas Delinte <nicolas.delinte@uclouvain.be>
6
6
  License-Expression: GPL-3.0-only
@@ -1,5 +1,5 @@
1
1
  """
2
2
  This package contains an UNVEIL, a lightweight tractography viewer implemented in python."""
3
3
 
4
- __version__ = "0.1.0"
4
+ __version__ = "0.2.0"
5
5
  __author__ = 'Nicolas Delinte'
@@ -2,13 +2,13 @@
2
2
  """
3
3
  Created on Tue Mar 4 13:03:28 2025
4
4
 
5
- @author: nicol
5
+ @author: DELINTE Nicolas
6
6
  """
7
7
  import sys
8
8
  import numpy as np
9
9
  import nibabel as nib
10
10
  import pyvista as pv
11
- from pyvistaqt import QtInteractor # For embedding PyVista in PyQt6
11
+ from pyvistaqt import QtInteractor
12
12
  from PyQt6.QtCore import Qt
13
13
  from PyQt6.QtGui import QAction
14
14
  from PyQt6.QtWidgets import (QApplication, QWidget, QHBoxLayout, QVBoxLayout,
@@ -214,6 +214,10 @@ class TrkViewer(QWidget):
214
214
  btn_screenshot = QPushButton("Screenshot")
215
215
  btn_screenshot.clicked.connect(self.take_screenshot)
216
216
  cam_layout.addWidget(btn_screenshot)
217
+ btn_gif = QPushButton("Create GIF")
218
+ btn_gif.setToolTip("This takes ~2min to save after animation end.")
219
+ btn_gif.clicked.connect(self.create_gif)
220
+ cam_layout.addWidget(btn_gif)
217
221
 
218
222
  global_layout.addLayout(cam_layout)
219
223
 
@@ -396,16 +400,52 @@ class TrkViewer(QWidget):
396
400
  def take_screenshot(self):
397
401
  """Take a screenshot of the current 3D view."""
398
402
  options = QFileDialog.Options()
399
- file_path, _ = QFileDialog.getSaveFileName(
400
- self,
401
- "Save Screenshot",
402
- "",
403
- "PNG Image (*.png);;JPEG Image (*.jpg);;TIFF Image (*.tif)",
404
- options=options
405
- )
403
+ file_path, _ = QFileDialog.getSaveFileName(self, "Save Screenshot", "",
404
+ "PNG Image (*.png);;JPEG Image (*.jpg);;TIFF Image (*.tif)",
405
+ options=options)
406
406
  if file_path:
407
407
  self.plotter.screenshot(file_path, transparent_background=True)
408
408
 
409
+ def create_gif(self):
410
+ """Create a 360° rotation GIF of the current 3D view."""
411
+ options = QFileDialog.Options()
412
+ file_path, _ = QFileDialog.getSaveFileName(self, "Save GIF", "",
413
+ "GIF Files (*.gif)",
414
+ options=options)
415
+
416
+ if not file_path:
417
+ return
418
+
419
+ # Ensure the file has a .gif extension
420
+ if not file_path.lower().endswith(".gif"):
421
+ file_path += ".gif"
422
+
423
+ # Use an offscreen plotter so the main one remains visible
424
+ offscreen = pv.Plotter(
425
+ off_screen=True, window_size=self.plotter.window_size)
426
+
427
+ # Copy all meshes and volumes from the main plotter to the offscreen one
428
+ for actor_name, actor in self.plotter.actors.items():
429
+ offscreen.add_actor(actor.copy())
430
+
431
+ # Match background color and camera
432
+ offscreen.background_color = self.plotter.background_color
433
+ offscreen.camera_position = self.plotter.camera_position
434
+ offscreen.camera.SetPosition(self.plotter.camera.GetPosition())
435
+ offscreen.camera.SetFocalPoint(self.plotter.camera.GetFocalPoint())
436
+ offscreen.camera.SetViewUp(self.plotter.camera.GetViewUp())
437
+
438
+ # Create the 360° rotation GIF
439
+ offscreen.open_gif(file_path, fps=20)
440
+ n_frames = 360
441
+ for i in range(n_frames):
442
+ offscreen.camera.Azimuth(360 / n_frames)
443
+ offscreen.render()
444
+ offscreen.write_frame()
445
+ self.plotter.camera.azimuth += 360 / n_frames
446
+ self.plotter.render()
447
+ offscreen.close()
448
+
409
449
  def update_trk_viewer(self, reset_camera=False):
410
450
 
411
451
  opacity = self.opacitySlider.value() / 100.0
@@ -508,8 +548,8 @@ class TrkViewer(QWidget):
508
548
  opacity=opacity, name='gii_surface',
509
549
  reset_camera=reset_camera)
510
550
  else:
511
- # self.plotter.remove_actor('gii_surface', reset_camera=reset_camera)
512
- self.plotter.actors['gii_surface'].visibility = False
551
+ self.plotter.remove_actor('gii_surface', reset_camera=reset_camera)
552
+ # self.plotter.actors['gii_surface'].visibility = False
513
553
 
514
554
 
515
555
  class MainWindow(QMainWindow):
@@ -518,7 +558,7 @@ class MainWindow(QMainWindow):
518
558
  self.viewer = TrkViewer()
519
559
  self.setCentralWidget(self.viewer)
520
560
  self.initMenuBar()
521
- self.setWindowTitle("Tractography Viewer with Menubar")
561
+ self.setWindowTitle("UNVEIL - Tractography Viewer")
522
562
 
523
563
  def initMenuBar(self):
524
564
  menubar = self.menuBar()
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unveil-python
3
- Version: 0.1.0
3
+ Version: 0.2.0
4
4
  Summary: Implementation of UNVEIL
5
5
  Author-email: Nicolas Delinte <nicolas.delinte@uclouvain.be>
6
6
  License-Expression: GPL-3.0-only
File without changes
File without changes
File without changes