Skip to content

Commit

Permalink
cleanup
Browse files Browse the repository at this point in the history
  • Loading branch information
mlavik1 committed Aug 25, 2024
1 parent 3b44143 commit bba1900
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 125 deletions.
78 changes: 78 additions & 0 deletions Assets/Editor/Utils/EditorDatasetImportUtils.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
using System.Collections.Generic;
using System.IO;
using System.Threading.Tasks;
using System;
using System.Linq;
using UnityEditor;
using UnityEngine;

namespace UnityVolumeRendering
{
public class EditorDatasetImportUtils
{
public static async Task<VolumeDataset[]> ImportDicomDirectoryAsync(string dir, ProgressHandler progressHandler)
{
Debug.Log("Async dataset load. Hold on.");

List<VolumeDataset> importedDatasets = new List<VolumeDataset>();
bool recursive = true;

// Read all files
IEnumerable<string> fileCandidates = Directory.EnumerateFiles(dir, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
.Where(p => p.EndsWith(".dcm", StringComparison.InvariantCultureIgnoreCase) || p.EndsWith(".dicom", StringComparison.InvariantCultureIgnoreCase) || p.EndsWith(".dicm", StringComparison.InvariantCultureIgnoreCase));

if (!fileCandidates.Any())
{
if (UnityEditor.EditorUtility.DisplayDialog("Could not find any DICOM files",
$"Failed to find any files with DICOM file extension.{Environment.NewLine}Do you want to include files without DICOM file extension?", "Yes", "No"))
{
fileCandidates = Directory.EnumerateFiles(dir, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
}
}

if (fileCandidates.Any())
{
progressHandler.StartStage(0.2f, "Loading DICOM series");

IImageSequenceImporter importer = ImporterFactory.CreateImageSequenceImporter(ImageSequenceFormat.DICOM);
IEnumerable<IImageSequenceSeries> seriesList = await importer.LoadSeriesAsync(fileCandidates, new ImageSequenceImportSettings { progressHandler = progressHandler });

progressHandler.EndStage();
progressHandler.StartStage(0.8f);

int seriesIndex = 0, numSeries = seriesList.Count();
foreach (IImageSequenceSeries series in seriesList)
{
progressHandler.StartStage(1.0f / numSeries, $"Importing series {seriesIndex + 1} of {numSeries}");
VolumeDataset dataset = await importer.ImportSeriesAsync(series, new ImageSequenceImportSettings { progressHandler = progressHandler });
if (dataset != null)
{
await OptionallyDownscale(dataset);
importedDatasets.Add(dataset);
}
seriesIndex++;
progressHandler.EndStage();
}

progressHandler.EndStage();
}
else
Debug.LogError("Could not find any DICOM files to import.");

return importedDatasets.ToArray();
}

public static async Task OptionallyDownscale(VolumeDataset dataset)
{
if (EditorPrefs.GetBool("DownscaleDatasetPrompt"))
{
if (EditorUtility.DisplayDialog("Optional DownScaling",
$"Do you want to downscale the dataset? The dataset's dimension is: {dataset.dimX} x {dataset.dimY} x {dataset.dimZ}", "Yes", "No"))
{
Debug.Log("Async dataset downscale. Hold on.");
await Task.Run(() => dataset.DownScaleData());
}
}
}
}
}
26 changes: 21 additions & 5 deletions Assets/Editor/VolumeRenderedObjectCustomInspector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -180,11 +180,27 @@ public override void OnInspectorGUI()
}
private static async void ImportPetScan(VolumeRenderedObject targetObject)
{
VolumeRenderedObject petObject = await VolumeRendererEditorFunctions.DicomImportAsync(true);
petObject.transferFunction.colourControlPoints = new List<TFColourControlPoint>() { new TFColourControlPoint(0.0f, Color.red), new TFColourControlPoint(1.0f, Color.red) };
petObject.transferFunction.GenerateTexture();
targetObject.SetSecondaryVolume(petObject);
petObject.gameObject.SetActive(false);
string dir = EditorUtility.OpenFolderPanel("Select a folder to load", "", "");
if (Directory.Exists(dir))
{
using (ProgressHandler progressHandler = new ProgressHandler(new EditorProgressView()))
{
progressHandler.StartStage(0.7f, "Importing PET dataset");
Task<VolumeDataset[]> importTask = EditorDatasetImportUtils.ImportDicomDirectoryAsync(dir, progressHandler);
await importTask;
progressHandler.EndStage();

progressHandler.StartStage(0.3f, "Spawning PET dataset");
Debug.Assert(importTask.Result.Length > 0);
VolumeRenderedObject petObject = await VolumeObjectFactory.CreateObjectAsync(importTask.Result[0]);
petObject.transform.position = targetObject.transform.position;
petObject.transferFunction.colourControlPoints = new List<TFColourControlPoint>() { new TFColourControlPoint(0.0f, Color.red), new TFColourControlPoint(1.0f, Color.red) };
petObject.transferFunction.GenerateTexture();
targetObject.SetSecondaryVolume(petObject);
petObject.gameObject.SetActive(false);
progressHandler.EndStage();
}
}
}
}
}
130 changes: 10 additions & 120 deletions Assets/Editor/VolumeRendererEditorFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,32 +33,25 @@ private static void ShowDatasetImporter()
[MenuItem("Volume Rendering/Load dataset/Load DICOM")]
private static void ShowDICOMImporter()
{
_ = DicomImportAsync(true);
}

[MenuItem("Volume Rendering/Load dataset/Load PET-CT DICOM")]
private static void ShowPETCTDICOMImporter()
{
PETCTDicomImportAsync();
DicomImportAsync(true);
}

[MenuItem("Assets/Volume Rendering/Import dataset/Import DICOM")]
private static void ImportDICOMAsset()
{
_ = DicomImportAsync(false);
DicomImportAsync(false);
}

public static async Task<VolumeRenderedObject> DicomImportAsync(bool spawnInScene)
private static async void DicomImportAsync(bool spawnInScene)
{
VolumeRenderedObject obj = null;
string dir = EditorUtility.OpenFolderPanel("Select a folder to load", "", "");
if (Directory.Exists(dir))
{
Debug.Log("Async dataset load. Hold on.");
using (ProgressHandler progressHandler = new ProgressHandler(new EditorProgressView()))
{
progressHandler.StartStage(0.7f, "Importing dataset");
Task<VolumeDataset[]> importTask = DicomImportDirectoryAsync(dir, progressHandler);
Task<VolumeDataset[]> importTask = EditorDatasetImportUtils.ImportDicomDirectoryAsync(dir, progressHandler);
await importTask;
progressHandler.EndStage();
progressHandler.StartStage(0.3f, "Spawning dataset");
Expand All @@ -67,7 +60,7 @@ public static async Task<VolumeRenderedObject> DicomImportAsync(bool spawnInScen
if (spawnInScene)
{
VolumeDataset dataset = importTask.Result[i];
obj = await VolumeObjectFactory.CreateObjectAsync(dataset);
VolumeRenderedObject obj = await VolumeObjectFactory.CreateObjectAsync(dataset);
obj.transform.position = new Vector3(i, 0, 0);
}
else
Expand All @@ -84,96 +77,6 @@ public static async Task<VolumeRenderedObject> DicomImportAsync(bool spawnInScen
{
Debug.LogError("Directory doesn't exist: " + dir);
}
return obj;
}

private static async void PETCTDicomImportAsync()
{
string dirCT = EditorUtility.OpenFolderPanel("Select a CT DICOM folder to load", "", "");
string dirPET = EditorUtility.OpenFolderPanel("Select a PET DICOM folder to load", "", "");
if (Directory.Exists(dirCT) && Directory.Exists(dirPET))
{
Debug.Log("Async dataset load. Hold on.");
using (ProgressHandler progressHandler = new ProgressHandler(new EditorProgressView()))
{
progressHandler.StartStage(0.35f, "Importing CT dataset");
Task<VolumeDataset[]> importTaskCT = DicomImportDirectoryAsync(dirCT, progressHandler);
await importTaskCT;
progressHandler.EndStage();
Debug.Assert(importTaskCT.Result.Length > 0);
progressHandler.StartStage(0.35f, "Importing PET dataset");
Task<VolumeDataset[]> importTaskPET = DicomImportDirectoryAsync(dirPET, progressHandler);
await importTaskPET;
progressHandler.EndStage();
Debug.Assert(importTaskPET.Result.Length > 0);
progressHandler.StartStage(0.3f, "Spawning dataset");
VolumeDataset datasetCT = importTaskCT.Result[0];
VolumeDataset datasetPET = importTaskPET.Result[0];
VolumeRenderedObject objCT = await VolumeObjectFactory.CreateObjectAsync(datasetCT);
VolumeRenderedObject objPET = await VolumeObjectFactory.CreateObjectAsync(datasetPET);
objPET.transferFunction.colourControlPoints = new List<TFColourControlPoint>() { new TFColourControlPoint(0.0f, Color.red), new TFColourControlPoint(1.0f, Color.red) };
objPET.transferFunction.GenerateTexture();
progressHandler.EndStage();
objCT.SetSecondaryVolume(objPET);
objPET.gameObject.SetActive(false);
}
}
else
{
Debug.LogError("Directory doesn't exist");
}
}

private static async Task<VolumeDataset[]> DicomImportDirectoryAsync(string dir, ProgressHandler progressHandler)
{
Debug.Log("Async dataset load. Hold on.");

List<VolumeDataset> importedDatasets = new List<VolumeDataset>();
bool recursive = true;

// Read all files
IEnumerable<string> fileCandidates = Directory.EnumerateFiles(dir, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly)
.Where(p => p.EndsWith(".dcm", StringComparison.InvariantCultureIgnoreCase) || p.EndsWith(".dicom", StringComparison.InvariantCultureIgnoreCase) || p.EndsWith(".dicm", StringComparison.InvariantCultureIgnoreCase));

if (!fileCandidates.Any())
{
if (UnityEditor.EditorUtility.DisplayDialog("Could not find any DICOM files",
$"Failed to find any files with DICOM file extension.{Environment.NewLine}Do you want to include files without DICOM file extension?", "Yes", "No"))
{
fileCandidates = Directory.EnumerateFiles(dir, "*.*", recursive ? SearchOption.AllDirectories : SearchOption.TopDirectoryOnly);
}
}

if (fileCandidates.Any())
{
progressHandler.StartStage(0.2f, "Loading DICOM series");

IImageSequenceImporter importer = ImporterFactory.CreateImageSequenceImporter(ImageSequenceFormat.DICOM);
IEnumerable<IImageSequenceSeries> seriesList = await importer.LoadSeriesAsync(fileCandidates, new ImageSequenceImportSettings { progressHandler = progressHandler });

progressHandler.EndStage();
progressHandler.StartStage(0.8f);

int seriesIndex = 0, numSeries = seriesList.Count();
foreach (IImageSequenceSeries series in seriesList)
{
progressHandler.StartStage(1.0f / numSeries, $"Importing series {seriesIndex + 1} of {numSeries}");
VolumeDataset dataset = await importer.ImportSeriesAsync(series, new ImageSequenceImportSettings { progressHandler = progressHandler });
if (dataset != null)
{
await OptionallyDownscale(dataset);
importedDatasets.Add(dataset);
}
seriesIndex++;
progressHandler.EndStage();
}

progressHandler.EndStage();
}
else
Debug.LogError("Could not find any DICOM files to import.");

return importedDatasets.ToArray();
}

[MenuItem("Volume Rendering/Load dataset/Load NRRD dataset")]
Expand Down Expand Up @@ -214,7 +117,7 @@ private static async void ImportNRRDDatasetAsync(bool spawnInScene)
progressHandler.ReportProgress(0.8f, "Creating object");
if (dataset != null)
{
await OptionallyDownscale(dataset);
await EditorDatasetImportUtils.OptionallyDownscale(dataset);
if (spawnInScene)
{
await VolumeObjectFactory.CreateObjectAsync(dataset);
Expand Down Expand Up @@ -266,7 +169,7 @@ private static async void ImportNIFTIDatasetAsync(bool spawnInScene)

if (dataset != null)
{
await OptionallyDownscale(dataset);
await EditorDatasetImportUtils.OptionallyDownscale(dataset);
if (spawnInScene)
{
await VolumeObjectFactory.CreateObjectAsync(dataset);
Expand Down Expand Up @@ -318,7 +221,7 @@ private static async void ImporImageFileDatasetAsync(bool spawnInScene)

if (dataset != null)
{
await OptionallyDownscale(dataset);
await EditorDatasetImportUtils.OptionallyDownscale(dataset);
if (spawnInScene)
{
await VolumeObjectFactory.CreateObjectAsync(dataset);
Expand Down Expand Up @@ -370,7 +273,7 @@ private static async void ImportParDatasetAsync(bool spawnInScene)

if (dataset != null)
{
await OptionallyDownscale(dataset);
await EditorDatasetImportUtils.OptionallyDownscale(dataset);
if (spawnInScene)
{
await VolumeObjectFactory.CreateObjectAsync(dataset);
Expand Down Expand Up @@ -422,7 +325,7 @@ private static async void ImportSequenceAsync()
VolumeDataset dataset = await importer.ImportSeriesAsync(series);
if (dataset != null)
{
await OptionallyDownscale(dataset);
await EditorDatasetImportUtils.OptionallyDownscale(dataset);
await VolumeObjectFactory.CreateObjectAsync(dataset);
}
}
Expand All @@ -433,19 +336,6 @@ private static async void ImportSequenceAsync()
}
}

private static async Task OptionallyDownscale(VolumeDataset dataset)
{
if (EditorPrefs.GetBool("DownscaleDatasetPrompt"))
{
if (EditorUtility.DisplayDialog("Optional DownScaling",
$"Do you want to downscale the dataset? The dataset's dimension is: {dataset.dimX} x {dataset.dimY} x {dataset.dimZ}", "Yes", "No"))
{
Debug.Log("Async dataset downscale. Hold on.");
await Task.Run(() => dataset.DownScaleData());
}
}
}

[MenuItem("Volume Rendering/Cross section/Cross section plane")]
private static void OnMenuItemClick()
{
Expand Down

0 comments on commit bba1900

Please sign in to comment.