Skip to content

Commit 3b32b60

Browse files
committed
Segmentation: Isolated rendre mode
1 parent 66c6e2c commit 3b32b60

File tree

5 files changed

+132
-28
lines changed

5 files changed

+132
-28
lines changed

Assets/Editor/VolumeRenderedObjectCustomInspector.cs

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -142,9 +142,9 @@ public override void OnInspectorGUI()
142142

143143
// Secondary volume
144144
secondaryVolumeSettings = EditorGUILayout.Foldout(secondaryVolumeSettings, "PET/overlay volume");
145-
VolumeDataset secondaryDataset = volrendObj.GetSecondaryDataset();
145+
OverlayType overlayType = volrendObj.GetOverlayType();
146146
TransferFunction secondaryTransferFunction = volrendObj.GetSecondaryTransferFunction();
147-
if (secondaryDataset == null)
147+
if (overlayType != OverlayType.Overlay)
148148
{
149149
if (GUILayout.Button("Load PET (NRRD, NIFTI)"))
150150
{
@@ -164,7 +164,7 @@ public override void OnInspectorGUI()
164164

165165
if (GUILayout.Button("Remove secondary volume"))
166166
{
167-
volrendObj.SetSecondaryDataset(null);
167+
volrendObj.SetOverlayDataset(null);
168168
}
169169
}
170170

@@ -177,20 +177,24 @@ public override void OnInspectorGUI()
177177
{
178178
EditorGUILayout.BeginHorizontal();
179179
SegmentationLabel segmentationlabel = segmentationLabels[i];
180+
EditorGUI.BeginChangeCheck();
180181
segmentationlabel.name = EditorGUILayout.TextField(segmentationlabel.name);
181182
segmentationlabel.colour = EditorGUILayout.ColorField(segmentationlabel.colour);
183+
bool changed = EditorGUI.EndChangeCheck();
182184
segmentationLabels[i] = segmentationlabel;
183185
if (GUILayout.Button("delete"))
184186
{
185-
segmentationLabels.RemoveAt(i);
186-
volrendObj.UpdateSegmentationLabels();
187+
volrendObj.RemoveSegmentation(segmentationlabel.id);
187188
}
188-
if (GUILayout.Button("test"))
189+
EditorGUILayout.EndHorizontal();
190+
if (changed)
189191
{
190192
volrendObj.UpdateSegmentationLabels();
191193
}
192-
EditorGUILayout.EndHorizontal();
193194
}
195+
196+
SegmentationRenderMode segmentationRendreMode = (SegmentationRenderMode)EditorGUILayout.EnumPopup("Render mode", volrendObj.GetSegmentationRenderMode());
197+
volrendObj.SetSegmentationRenderMode(segmentationRendreMode);
194198
}
195199
if (GUILayout.Button("Add segmentation (NRRD, NIFTI)"))
196200
{
@@ -200,6 +204,10 @@ public override void OnInspectorGUI()
200204
{
201205
ImportSegmentationDicom(volrendObj);
202206
}*/
207+
if (GUILayout.Button("Clear segmentations"))
208+
{
209+
volrendObj.ClearSegmentations();
210+
}
203211

204212
// Other settings
205213
GUILayout.Space(10);
@@ -242,7 +250,7 @@ private static async void ImportPetScan(VolumeRenderedObject targetObject)
242250
TransferFunction secondaryTransferFunction = ScriptableObject.CreateInstance<TransferFunction>();
243251
secondaryTransferFunction.colourControlPoints = new List<TFColourControlPoint>() { new TFColourControlPoint(0.0f, Color.red), new TFColourControlPoint(1.0f, Color.red) };
244252
secondaryTransferFunction.GenerateTexture();
245-
targetObject.SetSecondaryDataset(importTask.Result);
253+
targetObject.SetOverlayDataset(importTask.Result);
246254
targetObject.SetSecondaryTransferFunction(secondaryTransferFunction);
247255
}
248256
}
@@ -263,7 +271,7 @@ private static async void ImportPetScanDicom(VolumeRenderedObject targetObject)
263271
TransferFunction secondaryTransferFunction = ScriptableObject.CreateInstance<TransferFunction>();
264272
secondaryTransferFunction.colourControlPoints = new List<TFColourControlPoint>() { new TFColourControlPoint(0.0f, Color.red), new TFColourControlPoint(1.0f, Color.red) };
265273
secondaryTransferFunction.GenerateTexture();
266-
targetObject.SetSecondaryDataset(importTask.Result[0]);
274+
targetObject.SetOverlayDataset(importTask.Result[0]);
267275
targetObject.SetSecondaryTransferFunction(secondaryTransferFunction);
268276
}
269277
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace UnityVolumeRendering
2+
{
3+
public enum OverlayType
4+
{
5+
None,
6+
Overlay,
7+
Segmentation
8+
}
9+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
using UnityEngine;
2+
3+
namespace UnityVolumeRendering
4+
{
5+
[System.Serializable]
6+
public struct SegmentationLabel
7+
{
8+
public int id;
9+
public string name;
10+
public Color colour;
11+
}
12+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
namespace UnityVolumeRendering
2+
{
3+
[System.Serializable]
4+
public enum SegmentationRenderMode
5+
{
6+
OverlayColour,
7+
Isolate
8+
}
9+
}

Assets/Scripts/VolumeObject/VolumeRenderedObject.cs

Lines changed: 85 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -7,14 +7,6 @@
77

88
namespace UnityVolumeRendering
99
{
10-
[System.Serializable]
11-
public struct SegmentationLabel
12-
{
13-
public int id;
14-
public string name;
15-
public Color colour;
16-
}
17-
1810
[ExecuteInEditMode]
1911
public class VolumeRenderedObject : MonoBehaviour
2012
{
@@ -54,6 +46,12 @@ public class VolumeRenderedObject : MonoBehaviour
5446
[SerializeField, HideInInspector]
5547
private List<SegmentationLabel> segmentationLabels = new List<SegmentationLabel>();
5648

49+
[SerializeField, HideInInspector]
50+
private OverlayType overlayType = OverlayType.None;
51+
52+
[SerializeField, HideInInspector]
53+
private SegmentationRenderMode segmentationRenderMode = SegmentationRenderMode.OverlayColour;
54+
5755
// Minimum and maximum gradient threshold for lighting contribution. Values below min will be unlit, and between min and max will be partly shaded.
5856
[SerializeField, HideInInspector]
5957
private Vector2 gradientLightingThreshold = new Vector2(0.02f, 0.15f);
@@ -102,15 +100,9 @@ public SlicingPlane CreateSlicingPlane()
102100
return slicingPlaneComp;
103101
}
104102

105-
public VolumeDataset GetSecondaryDataset()
103+
public OverlayType GetOverlayType()
106104
{
107-
return this.secondaryDataset;
108-
}
109-
110-
public void SetSecondaryDataset(VolumeDataset dataset)
111-
{
112-
this.secondaryDataset = dataset;
113-
UpdateMaterialProperties();
105+
return this.overlayType;
114106
}
115107

116108
public TransferFunction GetSecondaryTransferFunction()
@@ -124,6 +116,34 @@ public void SetSecondaryTransferFunction(TransferFunction tf)
124116
UpdateMaterialProperties();
125117
}
126118

119+
public void SetOverlayDataset(VolumeDataset dataset)
120+
{
121+
if (dataset != null)
122+
{
123+
this.overlayType = OverlayType.Overlay;
124+
}
125+
else if(this.overlayType == OverlayType.Overlay)
126+
{
127+
this.overlayType = OverlayType.None;
128+
}
129+
this.secondaryDataset = dataset;
130+
UpdateMaterialProperties();
131+
}
132+
133+
public SegmentationRenderMode GetSegmentationRenderMode()
134+
{
135+
return segmentationRenderMode;
136+
}
137+
138+
public void SetSegmentationRenderMode(SegmentationRenderMode mode)
139+
{
140+
if (mode != segmentationRenderMode)
141+
{
142+
segmentationRenderMode = mode;
143+
UpdateMaterialProperties();
144+
}
145+
}
146+
127147
public List<SegmentationLabel> GetSegmentationLabels()
128148
{
129149
return segmentationLabels;
@@ -137,6 +157,8 @@ public void AddSegmentation(VolumeDataset dataset)
137157
return;
138158
}
139159

160+
overlayType = OverlayType.Segmentation;
161+
140162
int segmentationId = segmentationLabels.Count > 0 ? segmentationLabels.Max(l => l.id) + 1 : 1;
141163

142164
if (segmentationLabels.Count == 0)
@@ -161,10 +183,44 @@ public void AddSegmentation(VolumeDataset dataset)
161183
UpdateSegmentationLabels();
162184
}
163185

186+
public void RemoveSegmentation(int id)
187+
{
188+
int segmentationIndex = segmentationLabels.FindIndex(s => s.id == id);
189+
if (segmentationIndex != -1)
190+
{
191+
segmentationLabels.RemoveAt(segmentationIndex);
192+
}
193+
else
194+
{
195+
Debug.LogError($"Segmentation not found: {id}");
196+
}
197+
for (int i = 0; i < secondaryDataset.data.Length; i++)
198+
{
199+
secondaryDataset.data[i] = secondaryDataset.data[i] == id ? 0 : secondaryDataset.data[i];
200+
}
201+
secondaryDataset.RecalculateBounds();
202+
secondaryDataset.RecreateDataTexture();
203+
secondaryDataset.GetDataTexture().filterMode = FilterMode.Point;
204+
UpdateSegmentationLabels();
205+
}
206+
207+
public void ClearSegmentations()
208+
{
209+
if (overlayType == OverlayType.Segmentation)
210+
{
211+
secondaryDataset = null;
212+
secondaryTransferFunction = null;
213+
overlayType = OverlayType.None;
214+
}
215+
segmentationLabels.Clear();
216+
UpdateMaterialProperties();
217+
}
218+
164219
public void UpdateSegmentationLabels()
165220
{
166221
if (segmentationLabels.Count == 0)
167222
{
223+
UpdateMaterialProperties();
168224
return;
169225
}
170226

@@ -454,16 +510,26 @@ private void UpdateMatInternal(Texture3D dataTexture, Texture3D gradientTexture,
454510
meshRenderer.sharedMaterial.SetTexture("_GradientTex", gradientTexture);
455511
}
456512

457-
if (secondaryDataTexture != null)
513+
if (overlayType != OverlayType.None && secondaryDataTexture != null)
458514
{
459515
Texture2D secondaryTF = secondaryTransferFunction.GetTexture();
460516
meshRenderer.sharedMaterial.SetTexture("_SecondaryDataTex", secondaryDataTexture);
461517
meshRenderer.sharedMaterial.SetTexture("_SecondaryTFTex", secondaryTF);
462-
meshRenderer.sharedMaterial.EnableKeyword("SECONDARY_VOLUME_ON");
518+
if (overlayType == OverlayType.Segmentation && segmentationRenderMode == SegmentationRenderMode.Isolate)
519+
{
520+
meshRenderer.sharedMaterial.EnableKeyword("MULTIVOLUME_ISOLATE");
521+
meshRenderer.sharedMaterial.DisableKeyword("MULTIVOLUME_OVERLAY");
522+
}
523+
else if(overlayType == OverlayType.Overlay)
524+
{
525+
meshRenderer.sharedMaterial.EnableKeyword("MULTIVOLUME_OVERLAY");
526+
meshRenderer.sharedMaterial.DisableKeyword("MULTIVOLUME_ISOLATE");
527+
}
463528
}
464529
else
465530
{
466-
meshRenderer.sharedMaterial.DisableKeyword("SECONDARY_VOLUME_ON");
531+
meshRenderer.sharedMaterial.DisableKeyword("MULTIVOLUME_OVERLAY");
532+
meshRenderer.sharedMaterial.DisableKeyword("MULTIVOLUME_ISOLATE");
467533
}
468534

469535
if (meshRenderer.sharedMaterial.GetTexture("_NoiseTex") == null)

0 commit comments

Comments
 (0)