Skip to content

Use Hounsfield scale for transfer functions #217

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 6 additions & 4 deletions Assets/Editor/TransferFunctionEditorWindow.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace UnityVolumeRendering
{
public class TransferFunctionEditorWindow : EditorWindow
{
private TransferFunction tf = null;
private TransferFunctionInstance tfInstance = null;

private VolumeRenderedObject volRendObject = null;

Expand Down Expand Up @@ -49,7 +49,8 @@ private void OnGUI()
if (volRendObject == null)
return;

tf = volRendObject.transferFunction;
tfInstance = volRendObject.transferFunctionInstance;
TransferFunction tf = tfInstance.transferFunction;

Event currentEvent = new Event(Event.current);

Expand All @@ -62,7 +63,7 @@ private void OnGUI()
Rect outerRect = new Rect(0.0f, 0.0f, contentWidth, contentHeight);
Rect tfEditorRect = new Rect(outerRect.x + 20.0f, outerRect.y + 20.0f, outerRect.width - 40.0f, outerRect.height - 50.0f);

tfEditor.SetVolumeObject(volRendObject);
tfEditor.SetTransferFunctionInstnace(tfInstance);
tfEditor.DrawOnGUI(tfEditorRect);

// Save TF
Expand All @@ -76,7 +77,7 @@ private void OnGUI()
// Load TF
if(GUI.Button(new Rect(tfEditorRect.x + 75.0f, tfEditorRect.y + tfEditorRect.height + 20.0f, 70.0f, 30.0f), "Load"))
{
string filepath = EditorUtility.OpenFilePanel("Save transfer function", "", "tf");
string filepath = EditorUtility.OpenFilePanel("Load transfer function", "", "tf");
if(filepath != "")
{
TransferFunction newTF = TransferFunctionDatabase.LoadTransferFunction(filepath);
Expand All @@ -92,6 +93,7 @@ private void OnGUI()
if(GUI.Button(new Rect(tfEditorRect.x + 150.0f, tfEditorRect.y + tfEditorRect.height + 20.0f, 70.0f, 30.0f), "Clear"))
{
tf = ScriptableObject.CreateInstance<TransferFunction>();
tf.relativeScale = true;
tf.alphaControlPoints.Add(new TFAlphaControlPoint(0.2f, 0.0f));
tf.alphaControlPoints.Add(new TFAlphaControlPoint(0.8f, 1.0f));
tf.colourControlPoints.Add(new TFColourControlPoint(0.5f, new Color(0.469f, 0.354f, 0.223f, 1.0f)));
Expand Down
145 changes: 145 additions & 0 deletions Assets/Editor/TransferFunctionUpgraderWindow.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,145 @@
using System.IO;
using UnityEditor;
using UnityEngine;

namespace UnityVolumeRendering
{
public class TransferFunctionUpgraderWindow : EditorWindow
{
private enum TFConversionState
{
ReadyToImport,
ReadyToConvert,
ReadyToSave
}

private TransferFunction transferFunction = null;
private VolumeRenderedObject targetObject = null;
private string infoText = "";
private string errorText = "";
private string tfFilePath = "";

private TFConversionState state = TFConversionState.ReadyToImport;

public static void ShowWindow()
{
TransferFunctionUpgraderWindow wnd = new TransferFunctionUpgraderWindow();
wnd.Show();
}

private void OnGUI()
{
if (state == TFConversionState.ReadyToImport)
{
targetObject = null;
transferFunction = null;
}

GUIStyle headerStyle = new GUIStyle(EditorStyles.label);
headerStyle.fontSize = 20;

GUIStyle groupHeaderStyle = new GUIStyle(EditorStyles.label);
groupHeaderStyle.fontSize = 16;
groupHeaderStyle.fontStyle = FontStyle.Bold;

GUIStyle errorStyle = new GUIStyle(EditorStyles.label);
errorStyle.normal.textColor = Color.red;

GUIStyle infoStyle = new GUIStyle(EditorStyles.label);
infoStyle.wordWrap = true;

EditorGUILayout.LabelField("Transfer function upgrader tool", headerStyle);

EditorGUILayout.Space();

if (infoText != "")
{
EditorGUILayout.LabelField(infoText);
EditorGUILayout.Space();
}

if (errorText != "")
{
EditorGUILayout.LabelField(errorText, errorStyle);
EditorGUILayout.Space();
}

GUILayout.Label("Import", groupHeaderStyle);
if (GUILayout.Button("Load transfer function"))
{
tfFilePath = EditorUtility.OpenFilePanel("Load transfer function", "", "tf");
transferFunction = TransferFunctionDatabase.LoadTransferFunction(tfFilePath);
if (transferFunction == null)
errorText = "Invalid transfer function";
else
{
if (transferFunction.relativeScale)
{
infoText = "Old transfer function with relative scale detected. Please convert it.";
state = TFConversionState.ReadyToConvert;
}
else
{
infoText = "Transfer function already up-to-date. Nothing was done.";
}
}
}
EditorGUILayout.Space();

if (state == TFConversionState.ReadyToConvert || state == TFConversionState.ReadyToSave)
{
GUILayout.Label("Select target object (dataset)", groupHeaderStyle);
targetObject = EditorGUILayout.ObjectField("Target object", targetObject, typeof(VolumeRenderedObject), true) as VolumeRenderedObject;
if (targetObject != null && targetObject.dataset != null)
{
ConvertToAbsoluteTF(transferFunction, targetObject.dataset);
infoText = "The transfer function has been converted. Please save it.";
state = TFConversionState.ReadyToSave;
}
GUILayout.Label("Since the transfer function was using data values relative to a dataset," +
"we need a reference to this dataset in order to convert the values to Hounsfield scale, which is now the default.", infoStyle);
EditorGUILayout.Space();
}

if (state == TFConversionState.ReadyToSave)
{
GUILayout.Label("Save converted dataset", groupHeaderStyle);
if (targetObject == null || transferFunction == null)
{
state = TFConversionState.ReadyToImport;
return;
}

if (GUILayout.Button("Save transfer function"))
{
string filepath = EditorUtility.SaveFilePanel("Save transfer function", Path.GetDirectoryName(tfFilePath), Path.GetFileName(tfFilePath), "tf");
TransferFunctionDatabase.SaveTransferFunction(transferFunction, filepath);
infoText = "Transfer function saved. You can now import a new one.";
state = TFConversionState.ReadyToImport;
}
}
}

private void ConvertToAbsoluteTF(TransferFunction transferFunction, VolumeDataset dataset)
{
if (transferFunction.relativeScale)
{
float minValue = dataset.GetMinDataValue();
float maxValue = dataset.GetMaxDataValue();
for (int i = 0; i < transferFunction.colourControlPoints.Count; i++)
{
TFColourControlPoint point = transferFunction.colourControlPoints[i];
point.dataValue = Mathf.Lerp(minValue, maxValue, point.dataValue);
transferFunction.colourControlPoints[i] = point;
}
for (int i = 0; i < transferFunction.alphaControlPoints.Count; i++)
{
TFAlphaControlPoint point = transferFunction.alphaControlPoints[i];
point.dataValue = Mathf.Lerp(minValue, maxValue, point.dataValue);
transferFunction.alphaControlPoints[i] = point;
}
transferFunction.relativeScale = false;
}
}
}
}
11 changes: 11 additions & 0 deletions Assets/Editor/TransferFunctionUpgraderWindow.cs.meta

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 8 additions & 2 deletions Assets/Editor/VolumeRendererEditorFunctions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -372,7 +372,13 @@ private static void SpawnCutoutSphere()
VolumeObjectFactory.SpawnCutoutSphere(objects[0]);
}

[MenuItem("Volume Rendering/1D Transfer Function")]
[MenuItem("Volume Rendering/Transfer Function/Transfer function upgrader tool")]
private static void ShowTFUpgraderWindow()
{
TransferFunctionUpgraderWindow.ShowWindow();
}

[MenuItem("Volume Rendering/Transfer Function/1D Transfer Function editor")]
private static void Show1DTFWindow()
{
VolumeRenderedObject volRendObj = SelectionHelper.GetSelectedVolumeObject();
Expand All @@ -387,7 +393,7 @@ private static void Show1DTFWindow()
}
}

[MenuItem("Volume Rendering/2D Transfer Function")]
[MenuItem("Volume Rendering/Transfer Function/2D Transfer Function editor")]
private static void Show2DTFWindow()
{
TransferFunction2DEditorWindow.ShowWindow();
Expand Down
26 changes: 0 additions & 26 deletions Assets/Scripts/GUI/Components/DistanceMeasureTool.cs
Original file line number Diff line number Diff line change
Expand Up @@ -94,31 +94,5 @@ private void UpdateWindow(int windowID)

GUILayout.EndVertical();
}

private void OnLoadTransferFunction(RuntimeFileBrowser.DialogResult result)
{
if(!result.cancelled)
{
string extension = Path.GetExtension(result.path);
if(extension == ".tf")
{
TransferFunction tf = TransferFunctionDatabase.LoadTransferFunction(result.path);
if (tf != null)
{
targetObject.transferFunction = tf;
targetObject.SetTransferFunctionMode(TFRenderMode.TF1D);
}
}
if (extension == ".tf2d")
{
TransferFunction2D tf = TransferFunctionDatabase.LoadTransferFunction2D(result.path);
if (tf != null)
{
targetObject.transferFunction2D = tf;
targetObject.SetTransferFunctionMode(TFRenderMode.TF2D);
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion Assets/Scripts/GUI/Components/EditVolumeGUI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ private void OnLoadTransferFunction(RuntimeFileBrowser.DialogResult result)
TransferFunction tf = TransferFunctionDatabase.LoadTransferFunction(result.path);
if (tf != null)
{
targetObject.transferFunction = tf;
targetObject.SetTransferFunction(tf);
targetObject.SetTransferFunctionMode(TFRenderMode.TF1D);
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ namespace UnityVolumeRendering
public class RuntimeTransferFunctionEditor : MonoBehaviour
{
private static RuntimeTransferFunctionEditor instance = null;
private TransferFunction tf = null;
private TransferFunctionInstance tfInstance = null;
private VolumeRenderedObject volRendObject = null;

private int windowID;
Expand Down Expand Up @@ -60,15 +60,16 @@ private void UpdateWindow(int windowID)
if (volRendObject == null)
return;

tf = volRendObject.transferFunction;
tfInstance = volRendObject.transferFunctionInstance;
TransferFunction tf = tfInstance.transferFunction;

float contentWidth = Mathf.Min(WINDOW_WIDTH, (WINDOW_HEIGHT - 100.0f) * 2.0f);
float contentHeight = contentWidth * 0.5f;

Rect outerRect = new Rect(0.0f, 0.0f, contentWidth, contentHeight);
Rect tfEditorRect = new Rect(outerRect.x + 20.0f, outerRect.y + 20.0f, outerRect.width - 40.0f, outerRect.height - 50.0f);

tfEditor.SetVolumeObject(volRendObject);
tfEditor.SetTransferFunctionInstnace(tfInstance);
tfEditor.DrawOnGUI(tfEditorRect);

// Save TF
Expand Down Expand Up @@ -136,6 +137,7 @@ private void UpdateWindow(int windowID)
/// <param name="maxDistance">Threshold for maximum distance. Points further away than this won't get picked.</param>
private int PickColourControlPoint(float position, float maxDistance = 0.03f)
{
TransferFunction tf = tfInstance.transferFunction;
int nearestPointIndex = -1;
float nearestDist = 1000.0f;
for (int i = 0; i < tf.colourControlPoints.Count; i++)
Expand All @@ -157,6 +159,7 @@ private int PickColourControlPoint(float position, float maxDistance = 0.03f)
/// <param name="maxDistance">Threshold for maximum distance. Points further away than this won't get picked.</param>
private int PickAlphaControlPoint(Vector2 position, float maxDistance = 0.05f)
{
TransferFunction tf = tfInstance.transferFunction;
int nearestPointIndex = -1;
float nearestDist = 1000.0f;
for (int i = 0; i < tf.alphaControlPoints.Count; i++)
Expand Down
Loading