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); } } } }
public static void SaveTransferFunction(TransferFunction tf, string filepath) { TF1DSerialisationData data = new TF1DSerialisationData(); data.version = TF1DSerialisationData.VERSION_ID; data.colourPoints = new List <TFColourControlPoint>(tf.colourControlPoints); data.alphaPoints = new List <TFAlphaControlPoint>(tf.alphaControlPoints); string jsonstring = JsonUtility.ToJson(data); File.WriteAllText(filepath, jsonstring); }
public static VolumeRenderedObject CreateObject(VolumeDataset dataset) { GameObject outerObject = new GameObject("VolumeRenderedObject_" + dataset.datasetName); VolumeRenderedObject volObj = outerObject.AddComponent <VolumeRenderedObject>(); GameObject meshContainer = GameObject.Instantiate((GameObject)Resources.Load("VolumeContainer")); meshContainer.transform.parent = outerObject.transform; meshContainer.transform.localScale = Vector3.one; meshContainer.transform.localPosition = Vector3.zero; meshContainer.transform.parent = outerObject.transform; outerObject.transform.localRotation = Quaternion.Euler(90.0f, 0.0f, 0.0f); MeshRenderer meshRenderer = meshContainer.GetComponent <MeshRenderer>(); meshRenderer.sharedMaterial = new Material(meshRenderer.sharedMaterial); volObj.meshRenderer = meshRenderer; volObj.dataset = dataset; const int noiseDimX = 512; const int noiseDimY = 512; Texture2D noiseTexture = NoiseTextureGenerator.GenerateNoiseTexture(noiseDimX, noiseDimY); TransferFunction tf = TransferFunctionDatabase.CreateTransferFunction(); Texture2D tfTexture = tf.GetTexture(); volObj.transferFunction = tf; TransferFunction2D tf2D = TransferFunctionDatabase.CreateTransferFunction2D(); volObj.transferFunction2D = tf2D; meshRenderer.sharedMaterial.SetTexture("_DataTex", dataset.GetDataTexture()); meshRenderer.sharedMaterial.SetTexture("_GradientTex", null); meshRenderer.sharedMaterial.SetTexture("_NoiseTex", noiseTexture); meshRenderer.sharedMaterial.SetTexture("_TFTex", tfTexture); meshRenderer.sharedMaterial.EnableKeyword("MODE_DVR"); meshRenderer.sharedMaterial.DisableKeyword("MODE_MIP"); meshRenderer.sharedMaterial.DisableKeyword("MODE_SURF"); if (dataset.scaleX != 0.0f && dataset.scaleY != 0.0f && dataset.scaleZ != 0.0f) { float maxScale = Mathf.Max(dataset.scaleX, dataset.scaleY, dataset.scaleZ); volObj.transform.localScale = new Vector3(dataset.scaleX / maxScale, dataset.scaleY / maxScale, dataset.scaleZ / maxScale); } return(volObj); }
public static TransferFunction CreateTransferFunction() { TransferFunction tf = new TransferFunction(); tf.AddControlPoint(new TFColourControlPoint(0.0f, new Color(0.11f, 0.14f, 0.13f, 1.0f))); tf.AddControlPoint(new TFColourControlPoint(0.2415f, new Color(0.469f, 0.354f, 0.223f, 1.0f))); tf.AddControlPoint(new TFColourControlPoint(0.3253f, new Color(1.0f, 1.0f, 1.0f, 1.0f))); tf.AddControlPoint(new TFAlphaControlPoint(0.0f, 0.0f)); tf.AddControlPoint(new TFAlphaControlPoint(0.1787f, 0.0f)); tf.AddControlPoint(new TFAlphaControlPoint(0.2f, 0.024f)); tf.AddControlPoint(new TFAlphaControlPoint(0.28f, 0.03f)); tf.AddControlPoint(new TFAlphaControlPoint(0.4f, 0.546f)); tf.AddControlPoint(new TFAlphaControlPoint(0.547f, 0.5266f)); tf.GenerateTexture(); return(tf); }
public static TransferFunction LoadTransferFunction(string filepath) { if (!File.Exists(filepath)) { Debug.LogError(string.Format("File does not exist: {0}", filepath)); return(null); } string jsonstring = File.ReadAllText(filepath); TF1DSerialisationData data = JsonUtility.FromJson <TF1DSerialisationData>(jsonstring); Debug.Log(jsonstring); Debug.Log(data.colourPoints.ToString()); Debug.Log(data.alphaPoints.ToString()); TransferFunction tf = new TransferFunction(); tf.colourControlPoints = data.colourPoints; tf.alphaControlPoints = data.alphaPoints; return(tf); }
public static VolumeRenderedObject CreateObject(VolumeDataset dataset) { GameObject obj = GameObject.Instantiate((GameObject)Resources.Load("VolumeRenderedObject")); VolumeRenderedObject volObj = obj.GetComponent <VolumeRenderedObject>(); MeshRenderer meshRenderer = obj.GetComponent <MeshRenderer>(); meshRenderer.material = new Material(meshRenderer.sharedMaterial); volObj.dataset = dataset; const int noiseDimX = 512; const int noiseDimY = 512; Texture2D noiseTexture = NoiseTextureGenerator.GenerateNoiseTexture(noiseDimX, noiseDimY); TransferFunction tf = TransferFunctionDatabase.CreateTransferFunction(); Texture2D tfTexture = tf.GetTexture(); volObj.transferFunction = tf; tf.histogramTexture = HistogramTextureGenerator.GenerateHistogramTexture(dataset); TransferFunction2D tf2D = TransferFunctionDatabase.CreateTransferFunction2D(); volObj.transferFunction2D = tf2D; meshRenderer.sharedMaterial.SetTexture("_DataTex", dataset.GetDataTexture()); meshRenderer.sharedMaterial.SetTexture("_GradientTex", null); meshRenderer.sharedMaterial.SetTexture("_NoiseTex", noiseTexture); meshRenderer.sharedMaterial.SetTexture("_TFTex", tfTexture); meshRenderer.sharedMaterial.EnableKeyword("MODE_DVR"); meshRenderer.sharedMaterial.DisableKeyword("MODE_MIP"); meshRenderer.sharedMaterial.DisableKeyword("MODE_SURF"); return(volObj); }
private void OnGUI() { // Update selected object if (volRendObject == null) { volRendObject = SelectionHelper.GetSelectedVolumeObject(); } if (volRendObject == null) { return; } tf = volRendObject.transferFunction; Event currentEvent = new Event(Event.current); Color oldColour = GUI.color; float contentWidth = Mathf.Min(this.position.width - 20.0f, (this.position.height - 100.0f) * 2.0f); float contentHeight = contentWidth * 0.5f; Rect bgRect = new Rect(0.0f, 0.0f, contentWidth, contentHeight); // TODO: tf.GenerateTexture(); if (histTex == null) { histTex = HistogramTextureGenerator.GenerateHistogramTexture(volRendObject.dataset); } tfGUIMat.SetTexture("_TFTex", tf.GetTexture()); tfGUIMat.SetTexture("_HistTex", histTex); Graphics.DrawTexture(bgRect, tf.GetTexture(), tfGUIMat); Texture2D tfTexture = tf.GetTexture(); tfPaletteGUIMat.SetTexture("_TFTex", tf.GetTexture()); Graphics.DrawTexture(new Rect(bgRect.x, bgRect.y + bgRect.height + 20, bgRect.width, 20.0f), tfTexture, tfPaletteGUIMat); // Colour control points for (int iCol = 0; iCol < tf.colourControlPoints.Count; iCol++) { TFColourControlPoint colPoint = tf.colourControlPoints[iCol]; Rect ctrlBox = new Rect(bgRect.x + bgRect.width * colPoint.dataValue, bgRect.y + bgRect.height + 20, 10, 20); GUI.color = Color.red; GUI.skin.box.fontSize = 6; GUI.Box(ctrlBox, "*"); if (currentEvent.type == EventType.MouseDown && ctrlBox.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y))) { // Move colour control point if (currentEvent.button == 0) { movingColPointIndex = iCol; selectedColPointIndex = iCol; } // Remove it (if ctrl + right click) else if (currentEvent.button == 1 && currentEvent.control) { tf.colourControlPoints.RemoveAt(iCol); currentEvent.type = EventType.Ignore; selectedColPointIndex = -1; continue; } } else if (movingColPointIndex == iCol) { colPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f); } tf.colourControlPoints[iCol] = colPoint; } // Alpha control points for (int iAlpha = 0; iAlpha < tf.alphaControlPoints.Count; iAlpha++) { TFAlphaControlPoint alphaPoint = tf.alphaControlPoints[iAlpha]; Rect ctrlBox = new Rect(bgRect.x + bgRect.width * alphaPoint.dataValue, bgRect.y + (1.0f - alphaPoint.alphaValue) * bgRect.height, 10, 10); GUI.color = oldColour; GUI.skin.box.fontSize = 6; GUI.Box(ctrlBox, "*"); if (currentEvent.type == EventType.MouseDown && ctrlBox.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y))) { // Move alpha point if (currentEvent.button == 0) { movingAlphaPointIndex = iAlpha; } // Remove alpha point else if (currentEvent.button == 1 && currentEvent.control) { tf.alphaControlPoints.RemoveAt(iAlpha); currentEvent.type = EventType.Ignore; selectedColPointIndex = -1; continue; } } else if (movingAlphaPointIndex == iAlpha) { alphaPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f); alphaPoint.alphaValue = Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f); } tf.alphaControlPoints[iAlpha] = alphaPoint; } if (currentEvent.type == EventType.MouseUp) { movingColPointIndex = -1; movingAlphaPointIndex = -1; } // Add points if (currentEvent.type == EventType.MouseDown && currentEvent.button == 1) { if (bgRect.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y))) { tf.alphaControlPoints.Add(new TFAlphaControlPoint(Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f), Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f))); } else { tf.colourControlPoints.Add(new TFColourControlPoint(Mathf.Clamp((currentEvent.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f), Random.ColorHSV())); } selectedColPointIndex = -1; } if (selectedColPointIndex != -1) { TFColourControlPoint colPoint = tf.colourControlPoints[selectedColPointIndex]; colPoint.colourValue = EditorGUI.ColorField(new Rect(150, bgRect.y + bgRect.height + 50, 100.0f, 40.0f), colPoint.colourValue); tf.colourControlPoints[selectedColPointIndex] = colPoint; } if (GUI.Button(new Rect(0.0f, bgRect.y + bgRect.height + 50.0f, 70.0f, 30.0f), "Save")) { string filepath = EditorUtility.SaveFilePanel("Save transfer function", "", "default.tf", "tf"); if (filepath != "") { TransferFunctionDatabase.SaveTransferFunction(tf, filepath); } } if (GUI.Button(new Rect(75.0f, bgRect.y + bgRect.height + 50.0f, 70.0f, 30.0f), "Load")) { string filepath = EditorUtility.OpenFilePanel("Save transfer function", "", "tf"); if (filepath != "") { TransferFunction newTF = TransferFunctionDatabase.LoadTransferFunction(filepath); if (newTF != null) { volRendObject.transferFunction = tf = newTF; } } } GUI.skin.label.wordWrap = false; GUI.Label(new Rect(0.0f, bgRect.y + bgRect.height + 85.0f, 700.0f, 30.0f), "Left click to select and move a control point. Right click to add a control point, and ctrl + right click to delete."); GUI.color = oldColour; }
private void OnGUI() { // Update selected object if (volRendObject == null) { volRendObject = SelectionHelper.GetSelectedVolumeObject(); } if (volRendObject == null) { return; } tf = volRendObject.transferFunction; Event currentEvent = new Event(Event.current); Color oldColour = GUI.color; // Used for setting GUI.color when drawing UI elements float contentWidth = Mathf.Min(this.position.width, (this.position.height - 100.0f) * 2.0f); float contentHeight = contentWidth * 0.5f; // Interaction area (slightly larger than the histogram rect) Rect interactRect = new Rect(0.0f, 0.0f, contentWidth, contentHeight); // Histogram rect (histogram view and alpha control points) Rect histRect = new Rect(interactRect.x + 20.0f, interactRect.y + 20.0f, interactRect.width - 40.0f, interactRect.height - 40.0f); // Colour palette rect (colour control points) Rect paletteRect = new Rect(histRect.x, histRect.y + histRect.height + 20, histRect.width, 20.0f); // TODO: Don't do this every frame tf.GenerateTexture(); // Create histogram texture if (histTex == null) { if (SystemInfo.supportsComputeShaders) { histTex = HistogramTextureGenerator.GenerateHistogramTextureOnGPU(volRendObject.dataset); } else { histTex = HistogramTextureGenerator.GenerateHistogramTexture(volRendObject.dataset); } } // Draw histogram tfGUIMat.SetTexture("_TFTex", tf.GetTexture()); tfGUIMat.SetTexture("_HistTex", histTex); Graphics.DrawTexture(histRect, tf.GetTexture(), tfGUIMat); // Draw colour palette Texture2D tfTexture = tf.GetTexture(); tfPaletteGUIMat.SetTexture("_TFTex", tf.GetTexture()); Graphics.DrawTexture(new Rect(paletteRect.x, paletteRect.y, paletteRect.width, paletteRect.height), tfTexture, tfPaletteGUIMat); // Release selected colour/alpha points if mouse leaves window if (movingAlphaPointIndex != -1 && !interactRect.Contains(currentEvent.mousePosition)) { movingAlphaPointIndex = -1; } if (movingColPointIndex != -1 && !(currentEvent.mousePosition.x >= paletteRect.x && currentEvent.mousePosition.x <= paletteRect.x + paletteRect.width)) { movingColPointIndex = -1; } // Mouse down => Move or remove selected colour control point if (currentEvent.type == EventType.MouseDown && paletteRect.Contains(currentEvent.mousePosition)) { float mousePos = (currentEvent.mousePosition.x - paletteRect.x) / paletteRect.width; int pointIndex = PickColourControlPoint(mousePos); if (pointIndex != -1) { // Add control point if (currentEvent.button == 0 && !currentEvent.control) { movingColPointIndex = selectedColPointIndex = pointIndex; } // Remove control point else if (currentEvent.button == 1 && currentEvent.control) { tf.colourControlPoints.RemoveAt(pointIndex); currentEvent.type = EventType.Ignore; movingColPointIndex = selectedColPointIndex = -1; } } } else if (currentEvent.type == EventType.MouseUp) { movingColPointIndex = -1; } // Mouse down => Move or remove selected alpha control point if (currentEvent.type == EventType.MouseDown) { Vector2 mousePos = new Vector2((currentEvent.mousePosition.x - histRect.x) / histRect.width, 1.0f - (currentEvent.mousePosition.y - histRect.y) / histRect.height); int pointIndex = PickAlphaControlPoint(mousePos); if (pointIndex != -1) { // Add control point if (currentEvent.button == 0 && !currentEvent.control) { movingAlphaPointIndex = pointIndex; } // Remove control point else if (currentEvent.button == 1 && currentEvent.control) { tf.alphaControlPoints.RemoveAt(pointIndex); currentEvent.type = EventType.Ignore; selectedColPointIndex = -1; } } } // Move selected alpha control point if (movingAlphaPointIndex != -1) { TFAlphaControlPoint alphaPoint = tf.alphaControlPoints[movingAlphaPointIndex]; alphaPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - histRect.x) / histRect.width, 0.0f, 1.0f); alphaPoint.alphaValue = Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - histRect.y) / histRect.height, 0.0f, 1.0f); tf.alphaControlPoints[movingAlphaPointIndex] = alphaPoint; } // Move selected colour control point if (movingColPointIndex != -1) { TFColourControlPoint colPoint = tf.colourControlPoints[movingColPointIndex]; colPoint.dataValue = Mathf.Clamp((currentEvent.mousePosition.x - paletteRect.x) / paletteRect.width, 0.0f, 1.0f); tf.colourControlPoints[movingColPointIndex] = colPoint; } // Draw colour control points for (int iCol = 0; iCol < tf.colourControlPoints.Count; iCol++) { TFColourControlPoint colPoint = tf.colourControlPoints[iCol]; Rect ctrlBox = new Rect(histRect.x + histRect.width * colPoint.dataValue, histRect.y + histRect.height + 20, 10, 20); GUI.color = Color.red; GUI.skin.box.fontSize = 6; GUI.Box(ctrlBox, "*"); } // Draw alpha control points for (int iAlpha = 0; iAlpha < tf.alphaControlPoints.Count; iAlpha++) { const int pointSize = 10; TFAlphaControlPoint alphaPoint = tf.alphaControlPoints[iAlpha]; Rect ctrlBox = new Rect(histRect.x + histRect.width * alphaPoint.dataValue - pointSize / 2, histRect.y + (1.0f - alphaPoint.alphaValue) * histRect.height - pointSize / 2, pointSize, pointSize); GUI.color = Color.red; GUI.skin.box.fontSize = 6; GUI.Box(ctrlBox, "*"); GUI.color = oldColour; } if (currentEvent.type == EventType.MouseUp) { movingColPointIndex = -1; movingAlphaPointIndex = -1; } // Add points if (currentEvent.type == EventType.MouseDown && currentEvent.button == 1) { if (histRect.Contains(new Vector2(currentEvent.mousePosition.x, currentEvent.mousePosition.y))) { tf.alphaControlPoints.Add(new TFAlphaControlPoint(Mathf.Clamp((currentEvent.mousePosition.x - histRect.x) / histRect.width, 0.0f, 1.0f), Mathf.Clamp(1.0f - (currentEvent.mousePosition.y - histRect.y) / histRect.height, 0.0f, 1.0f))); } else { tf.colourControlPoints.Add(new TFColourControlPoint(Mathf.Clamp((currentEvent.mousePosition.x - histRect.x) / histRect.width, 0.0f, 1.0f), Random.ColorHSV())); } selectedColPointIndex = -1; } // Save TF if (GUI.Button(new Rect(histRect.x, histRect.y + histRect.height + 50.0f, 70.0f, 30.0f), "Save")) { string filepath = EditorUtility.SaveFilePanel("Save transfer function", "", "default.tf", "tf"); if (filepath != "") { TransferFunctionDatabase.SaveTransferFunction(tf, filepath); } } // Load TF if (GUI.Button(new Rect(histRect.x + 75.0f, histRect.y + histRect.height + 50.0f, 70.0f, 30.0f), "Load")) { string filepath = EditorUtility.OpenFilePanel("Save transfer function", "", "tf"); if (filepath != "") { TransferFunction newTF = TransferFunctionDatabase.LoadTransferFunction(filepath); if (newTF != null) { volRendObject.transferFunction = tf = newTF; } } } // Clear TF if (GUI.Button(new Rect(histRect.x + 150.0f, histRect.y + histRect.height + 50.0f, 70.0f, 30.0f), "Clear")) { tf = volRendObject.transferFunction = new TransferFunction(); 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))); selectedColPointIndex = -1; } // Colour picker if (selectedColPointIndex != -1) { TFColourControlPoint colPoint = tf.colourControlPoints[selectedColPointIndex]; colPoint.colourValue = EditorGUI.ColorField(new Rect(histRect.x + 225, histRect.y + histRect.height + 50, 100.0f, 40.0f), colPoint.colourValue); tf.colourControlPoints[selectedColPointIndex] = colPoint; } GUI.skin.label.wordWrap = false; GUI.Label(new Rect(histRect.x, histRect.y + histRect.height + 85.0f, 720.0f, 30.0f), "Left click to select and move a control point. Right click to add a control point, and ctrl + right click to delete."); GUI.color = oldColour; }