Ejemplo n.º 1
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);
    }
    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);
    }
    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;
    }