Exemplo n.º 1
0
    private void ImportDataset()
    {
        DatasetImporterBase importer = null;

        switch (datasetType)
        {
        case DatasetType.Raw:
        {
            importer = new RawDatasetImporter(fileToImport, dimX, dimY, dimZ, DataContentFormat.Int16, 6);
            break;
        }
        }

        VolumeDataset dataset = null;

        if (importer != null)
        {
            dataset = importer.Import();
        }

        if (dataset != null)
        {
            VolumeRenderedObject obj = VolumeObjectFactory.CreateObject(dataset);
        }
        else
        {
            Debug.LogError("Failed to import datset");
        }

        this.Close();
    }
Exemplo n.º 2
0
    private VolumeRenderedObject Import(string dir)
    {
        if (Directory.Exists(dir))
        {
            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())
            {
                DICOMImporter importer = new DICOMImporter(fileCandidates, Path.GetFileName(dir));
                VolumeDataset dataset  = importer.Import();
                if (dataset != null)
                {
                    VolumeRenderedObject vo = VolumeObjectFactory.CreateObject(dataset);
                    vo.transform.Rotate(new Vector3(180, 0, 0));
                    return(vo);
                }
            }
            else
            {
                Debug.LogError("Could not find any DICOM files to import.");
            }
        }
        return(null);
    }
    public override void OnInspectorGUI()
    {
        VolumeRenderedObject myTarget = (VolumeRenderedObject)target;

        RenderMode oldRenderMode = myTarget.GetRemderMode();
        RenderMode newRenderMode = (RenderMode)EditorGUILayout.EnumPopup("Render mode", oldRenderMode);

        if (newRenderMode != oldRenderMode)
        {
            myTarget.SetRenderMode(newRenderMode);
        }
    }
Exemplo n.º 4
0
    private void UpdateBrain(VolumeRenderedObject vro)
    {
        if (vro != null)
        {
            /* update renderer and bounds */
            // volume data is stored in child gameobject
            rend = vro.transform.GetChild(0).GetComponent <Renderer>();

            Vector3 center = rend.bounds.center;
            float   radius = rend.bounds.extents.magnitude;

            float x = rend.bounds.extents.x;
            float y = rend.bounds.extents.y;
            float z = rend.bounds.extents.z;

            // update position so that the world origin point is at the corner of brain
            vro.transform.position = new Vector3(x, y, z);
        }
    }
Exemplo n.º 5
0
    private void ImportDataset()
    {
        DatasetImporterBase importer = null;

        switch (datasetType)
        {
        case DatasetType.Raw:
        {
            importer = new RawDatasetImporter(fileToImport, dimX, dimY, dimZ, DataContentFormat.Int16, 6);
            break;
        }

        case DatasetType.DICOM:
        {
            throw new System.NotImplementedException("TODO: implement support for DICOM files");
        }
        }

        VolumeDataset dataset = null;

        if (importer != null)
        {
            dataset = importer.Import();
        }

        if (dataset != null)
        {
            VolumeRenderedObject obj = VolumeObjectFactory.CreateObject(dataset);
        }
        else
        {
            Debug.LogError("Failed to import datset");
        }

        this.Close();
    }
    private void OnGUI()
    {
        SlicingPlane[] spawnedPlanes = FindObjectsOfType <SlicingPlane>();

        if (spawnedPlanes.Length > 0)
        {
            selectedPlaneIndex = selectedPlaneIndex % spawnedPlanes.Length;
        }

        float bgWidth = Mathf.Min(this.position.width - 20.0f, (this.position.height - 50.0f) * 2.0f);
        Rect  bgRect  = new Rect(0.0f, 0.0f, bgWidth, bgWidth * 0.5f);

        if (selectedPlaneIndex != -1 && spawnedPlanes.Length > 0)
        {
            SlicingPlane planeObj = spawnedPlanes[System.Math.Min(selectedPlaneIndex, spawnedPlanes.Length - 1)];
            // Draw the slice view
            Material mat = planeObj.GetComponent <MeshRenderer>().sharedMaterial;
            Graphics.DrawTexture(bgRect, mat.GetTexture("_DataTex"), mat);

            // Handle mouse click inside slice view (activates moving the plane with mouse)
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && bgRect.Contains(new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y)))
            {
                handleMouseMovement = true;
                prevMousePos        = Event.current.mousePosition;
            }

            // Handle mouse movement (move the plane)
            if (handleMouseMovement)
            {
                Vector2 mouseOffset = (Event.current.mousePosition - prevMousePos) / new Vector2(bgRect.width, bgRect.height);
                if (Mathf.Abs(mouseOffset.y) > 0.00001f)
                {
                    planeObj.transform.Translate(Vector3.up * mouseOffset.y);
                    prevMousePos = Event.current.mousePosition;
                }
            }
        }

        if (Event.current.type == EventType.MouseUp)
        {
            handleMouseMovement = false;
        }

        // Show buttons for changing the active plane
        if (spawnedPlanes.Length > 0)
        {
            if (GUI.Button(new Rect(0.0f, bgRect.y + bgRect.height + 20.0f, 100.0f, 30.0f), "previous\nplane"))
            {
                selectedPlaneIndex         = (selectedPlaneIndex - 1) % spawnedPlanes.Length;
                Selection.activeGameObject = spawnedPlanes[selectedPlaneIndex].gameObject;
            }
            if (GUI.Button(new Rect(120.0f, bgRect.y + bgRect.height + 20.0f, 100.0f, 30.0f), "next\nplane"))
            {
                selectedPlaneIndex         = (selectedPlaneIndex + 1) % spawnedPlanes.Length;
                Selection.activeGameObject = spawnedPlanes[selectedPlaneIndex].gameObject;
            }
        }

        // Show button for adding new plane
        if (GUI.Button(new Rect(240.0f, bgRect.y + bgRect.height + 20.0f, 100.0f, 30.0f), "add\nplane"))
        {
            VolumeRenderedObject volRend = FindObjectOfType <VolumeRenderedObject>();
            if (volRend != null)
            {
                selectedPlaneIndex = spawnedPlanes.Length;
                volRend.CreateSlicingPlane();
            }
        }

        // Show hint
        if (spawnedPlanes.Length > 0)
        {
            GUI.Label(new Rect(0.0f, bgRect.y + bgRect.height + 60.0f, 450.0f, 30.0f), "Move plane by left clicking in the above view and dragging the mouse,\n or simply move it in the object hierarchy.");
        }
    }
    private void OnGUI()
    {
        VolumeRenderedObject volRend = FindObjectOfType <VolumeRenderedObject>();

        if (volRend == null)
        {
            return;
        }
        tf = volRend.transferFunction;

        Color oldColour = GUI.color;
        float bgWidth   = Mathf.Min(this.position.width - 20.0f, (this.position.height - 50.0f) * 2.0f);
        Rect  bgRect    = new Rect(0.0f, 0.0f, bgWidth, bgWidth * 0.5f);

        tf.GenerateTexture();

        histogramMaterial.SetTexture("_TFTex", tf.GetTexture());
        histogramMaterial.SetTexture("_HistTex", tf.histogramTexture);
        Graphics.DrawTexture(bgRect, tf.GetTexture(), histogramMaterial);

        Texture2D tfTexture = tf.GetTexture();

        colorBarMaterial.SetTexture("_TFTex", tf.GetTexture());
        Graphics.DrawTexture(new Rect(bgRect.x, bgRect.y + bgRect.height + 20, bgRect.width, 20.0f), tfTexture, colorBarMaterial);

        // Colour control points
        for (int iCol = 0; iCol < tf.colourControlPoints.Count; iCol++)
        {
            ControlPointColor 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 = 8;
            GUI.Box(ctrlBox, "|");
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && ctrlBox.Contains(new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y)))
            {
                movingColPointIndex   = iCol;
                selectedColPointIndex = iCol;
            }
            else if (movingColPointIndex == iCol)
            {
                colPoint.dataValue = Mathf.Clamp((Event.current.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++)
        {
            ControlPointAlpha 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, "a");
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && ctrlBox.Contains(new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y)))
            {
                movingAlphaPointIndex = iAlpha;
            }
            else if (movingAlphaPointIndex == iAlpha)
            {
                alphaPoint.dataValue  = Mathf.Clamp((Event.current.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f);
                alphaPoint.alphaValue = Mathf.Clamp(1.0f - (Event.current.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f);
            }
            tf.alphaControlPoints[iAlpha] = alphaPoint;
        }

        if (Event.current.type == EventType.MouseUp)
        {
            movingColPointIndex   = -1;
            movingAlphaPointIndex = -1;
        }

        if (Event.current.type == EventType.MouseDown && Event.current.button == 1)
        {
            if (bgRect.Contains(new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y)))
            {
                tf.alphaControlPoints.Add(
                    tf.CreateControlPointAlpha(
                        Mathf.Clamp((Event.current.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f),
                        Mathf.Clamp(1.0f - (Event.current.mousePosition.y - bgRect.y) / bgRect.height, 0.0f, 1.0f)
                        ));
            }
            else
            {
                tf.colourControlPoints.Add(tf.CreateControlPointColor(Mathf.Clamp((Event.current.mousePosition.x - bgRect.x) / bgRect.width, 0.0f, 1.0f), Random.ColorHSV()));
            }
            selectedColPointIndex = -1;
        }

        if (selectedColPointIndex != -1)
        {
            ControlPointColor colPoint = tf.colourControlPoints[selectedColPointIndex];
            colPoint.colourValue = EditorGUI.ColorField(new Rect(bgRect.x, bgRect.y + bgRect.height + 50, 100.0f, 40.0f), colPoint.colourValue);
            tf.colourControlPoints[selectedColPointIndex] = colPoint;
        }

        // TEST!!! TODO
        volRend.GetComponent <MeshRenderer>().sharedMaterial.SetTexture("_TFTex", tfTexture);
        volRend.GetComponent <MeshRenderer>().sharedMaterial.DisableKeyword("TF2D_ON");

        GUI.color = oldColour;
    }
Exemplo n.º 8
0
 public void OnSegmentationButtonClicked()
 {
     brainSeg = Import(completePath + "_seg");
     brainSeg.transform.GetChild(0).GetComponent <Renderer>().material = matBrainSeg;
     UpdateBrain(brainSeg);
 }
Exemplo n.º 9
0
 public void OnImportButtonClicked()
 {
     brain = Import(completePath + "_flair");
     UpdateBrain(brain);
 }
    public VolumeRenderedObject CreateVolumeRenderedObject(VolumeDataset dataset)
    {
        GameObject go = GameObject.Instantiate(volumeObjectPrefab) as GameObject;

        go.transform.SetParent(Program.instance.operationOverlay.transform);
        go.transform.localPosition = new Vector3(-0.0083f, 0.0426f, 0.0083f);
        go.transform.rotation      = Quaternion.Euler(-20f, 180f, 180f);

        VolumeRenderedObject volObj       = go.GetComponent <VolumeRenderedObject>();
        MeshRenderer         meshRenderer = go.GetComponent <MeshRenderer>();

        volObj.dataset = dataset;

        int dimX = dataset.dimX;
        int dimY = dataset.dimY;
        int dimZ = dataset.dimZ;

        int maxRange = dataset.maxDataValue - dataset.minDataValue;

        Color[] cols = new Color[dataset.data.Length];
        for (int x = 0; x < dataset.dimX; x++)
        {
            for (int y = 0; y < dataset.dimY; y++)
            {
                for (int z = 0; z < dataset.dimZ; z++)
                {
                    int iData = x + y * dimX + z * (dimX * dimY);

                    int x1 = dataset.data[Mathf.Min(x + 1, dimX - 1) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int x2 = dataset.data[Mathf.Max(x - 1, 0) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int y1 = dataset.data[x + Mathf.Min(y + 1, dimY - 1) * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int y2 = dataset.data[x + Mathf.Max(y - 1, 0) * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int z1 = dataset.data[x + y * dataset.dimX + Mathf.Min(z + 1, dimZ - 1) * (dataset.dimX * dataset.dimY)];
                    int z2 = dataset.data[x + y * dataset.dimX + Mathf.Max(z - 1, 0) * (dataset.dimX * dataset.dimY)];

                    Vector3 grad = new Vector3((x2 - x1) / (float)maxRange, (y2 - y1) / (float)maxRange, (z2 - z1) / (float)maxRange);

                    cols[iData] = new Color(grad.x, grad.y, grad.z, (float)dataset.data[iData] / (float)dataset.maxDataValue);
                }
            }
        }

        dataset.texture.SetPixels(cols);
        dataset.texture.Apply();

        Texture3D tex = dataset.texture;

        const int noiseDimX    = 512;
        const int noiseDimY    = 512;
        Texture2D noiseTexture = NoiseTextureGenerator.GenerateNoiseTexture(noiseDimX, noiseDimY);

        TransferFunction tf = Program.instance.transferFunctionManager.CreateTransferFunction();

        Texture2D tfTexture = tf.GetTexture();

        volObj.transferFunction = tf;

        tf.histogramTexture = HistogramTextureGenerator.GenerateHistogramTexture(dataset);

        TransferFunction2D tf2D = new TransferFunction2D();

        tf2D.AddBox(0.05f, 0.1f, 0.8f, 0.7f, Color.white, 0.4f);
        volObj.transferFunction2D = tf2D;

        meshRenderer.sharedMaterial.SetTexture("_DataTex", tex);
        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);
    }
Exemplo n.º 11
0
    public static VolumeRenderedObject CreateObject(VolumeDataset dataset)
    {
        GameObject           obj          = GameObject.Instantiate((GameObject)Resources.Load("VolumeRenderedObject"));
        VolumeRenderedObject volObj       = obj.GetComponent <VolumeRenderedObject>();
        MeshRenderer         meshRenderer = obj.GetComponent <MeshRenderer>();

        volObj.dataset = dataset;

        int dimX = dataset.dimX;
        int dimY = dataset.dimY;
        int dimZ = dataset.dimZ;

        int maxRange = dataset.maxDataValue - dataset.minDataValue;

        Color[] cols = new Color[dataset.data.Length];
        for (int x = 0; x < dataset.dimX; x++)
        {
            for (int y = 0; y < dataset.dimY; y++)
            {
                for (int z = 0; z < dataset.dimZ; z++)
                {
                    int iData = x + y * dimX + z * (dimX * dimY);

                    int x1 = dataset.data[Math.Min(x + 1, dimX - 1) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int x2 = dataset.data[Math.Max(x - 1, 0) + y * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int y1 = dataset.data[x + Math.Min(y + 1, dimY - 1) * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int y2 = dataset.data[x + Math.Max(y - 1, 0) * dataset.dimX + z * (dataset.dimX * dataset.dimY)];
                    int z1 = dataset.data[x + y * dataset.dimX + Math.Min(z + 1, dimZ - 1) * (dataset.dimX * dataset.dimY)];
                    int z2 = dataset.data[x + y * dataset.dimX + Math.Max(z - 1, 0) * (dataset.dimX * dataset.dimY)];

                    Vector3 grad = new Vector3((x2 - x1) / (float)maxRange, (y2 - y1) / (float)maxRange, (z2 - z1) / (float)maxRange);

                    cols[iData] = new Color(grad.x, grad.y, grad.z, (float)dataset.data[iData] / (float)dataset.maxDataValue);
                }
            }
        }

        dataset.texture.SetPixels(cols);
        dataset.texture.Apply();

        Texture3D tex = dataset.texture;

        const int noiseDimX    = 512;
        const int noiseDimY    = 512;
        Texture2D noiseTexture = NoiseTextureGenerator.GenerateNoiseTexture(noiseDimX, noiseDimY);

        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();
        Texture2D tfTexture = tf.GetTexture();

        volObj.transferFunction = tf;

        tf.histogramTexture = HistogramTextureGenerator.GenerateHistogramTexture(dataset);

        TransferFunction2D tf2D = new TransferFunction2D();

        tf2D.AddBox(0.05f, 0.1f, 0.8f, 0.7f, Color.white, 0.4f);
        volObj.transferFunction2D = tf2D;

        meshRenderer.sharedMaterial.SetTexture("_DataTex", tex);
        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()
    {
        VolumeRenderedObject volRend = FindObjectOfType <VolumeRenderedObject>();

        if (volRend == null)
        {
            return;
        }

        if (hist2DTex == null)
        {
            hist2DTex = HistogramTextureGenerator.Generate2DHistogramTexture(volRend.dataset);
        }

        TransferFunction2D tf2d = volRend.transferFunction2D;

        // Calculate GUI width (minimum of window width and window height * 2)
        float bgWidth = Mathf.Min(this.position.width - 20.0f, (this.position.height - 250.0f) * 2.0f);
        // Draw the histogram
        Rect histRect = new Rect(0.0f, 0.0f, bgWidth, bgWidth * 0.5f);

        Graphics.DrawTexture(histRect, hist2DTex);
        // Draw the TF texture (showing the rectangles)
        tfGUIMat.SetTexture("_TFTex", tf2d.GetTexture());
        Graphics.DrawTexture(histRect, tf2d.GetTexture(), tfGUIMat);

        // Handle mouse click in box
        for (int iBox = 0; iBox < tf2d.boxes.Count; iBox++)
        {
            TransferFunction2D.TF2DBox box = tf2d.boxes[iBox];
            Rect boxRect = new Rect(histRect.x + box.rect.x * histRect.width, histRect.y + (1.0f - box.rect.height - box.rect.y) * histRect.height, box.rect.width * histRect.width, box.rect.height * histRect.height);
            if (Event.current.type == EventType.MouseDown && Event.current.button == 0 && boxRect.Contains(new Vector2(Event.current.mousePosition.x, Event.current.mousePosition.y)))
            {
                selectedBoxIndex = iBox;
            }
        }

        float startX = histRect.x;
        float startY = histRect.y + histRect.height + 10;

        // Show GUI for editing selected rectangle
        if (selectedBoxIndex != -1)
        {
            EditorGUI.BeginChangeCheck();
            TransferFunction2D.TF2DBox box = tf2d.boxes[selectedBoxIndex];
            float oldX = box.rect.x;
            float oldY = box.rect.y;
            box.rect.x      = EditorGUI.Slider(new Rect(startX, startY, 200.0f, 20.0f), "x", box.rect.x, 0.0f, 0.99f);
            box.rect.width  = EditorGUI.Slider(new Rect(startX + 220.0f, startY, 200.0f, 20.0f), "width", oldX + box.rect.width, box.rect.x + 0.01f, 1.0f) - box.rect.x;
            box.rect.y      = EditorGUI.Slider(new Rect(startX, startY + 50, 200.0f, 20.0f), "y", box.rect.y, 0.0f, 1.0f);
            box.rect.height = EditorGUI.Slider(new Rect(startX + 220.0f, startY + 50, 200.0f, 20.0f), "height", oldY + box.rect.height, box.rect.y + 0.01f, 1.0f) - box.rect.y;
            box.colour      = EditorGUI.ColorField(new Rect(startX + 450.0f, startY + 10, 100.0f, 20.0f), box.colour);
            box.minAlpha    = EditorGUI.Slider(new Rect(startX + 450.0f, startY + 30, 200.0f, 20.0f), "min alpha", box.minAlpha, 0.0f, 1.0f);
            box.alpha       = EditorGUI.Slider(new Rect(startX + 450.0f, startY + 60, 200.0f, 20.0f), "max alpha", box.alpha, 0.0f, 1.0f);

            tf2d.boxes[selectedBoxIndex] = box;
            needsRegenTexture           |= EditorGUI.EndChangeCheck();
        }
        else
        {
            EditorGUI.LabelField(new Rect(startX, startY, this.position.width - startX, 50.0f), "Select a rectangle in the above view, or add a new one.");
        }

        // Add new rectangle
        if (GUI.Button(new Rect(startX, startY + 100, 150.0f, 40.0f), "Add rectangle"))
        {
            tf2d.AddBox(0.1f, 0.1f, 0.8f, 0.8f, Color.white, 0.5f);
            needsRegenTexture = true;
        }
        // Remove selected shape
        if (selectedBoxIndex != -1)
        {
            if (GUI.Button(new Rect(startX, startY + 150, 150.0f, 40.0f), "Remove selected shape"))
            {
                tf2d.boxes.RemoveAt(selectedBoxIndex);
                needsRegenTexture = true;
            }
        }

        // TODO: regenerate on add/remove/modify (and do it async)
        if (needsRegenTexture)
        {
            tf2d.GenerateTexture();
            needsRegenTexture = false;
        }
        volRend.GetComponent <MeshRenderer>().sharedMaterial.SetTexture("_TFTex", tf2d.GetTexture());
        volRend.GetComponent <MeshRenderer>().sharedMaterial.EnableKeyword("TF2D_ON");

        return;
    }