Example #1
0
        public void UpdateTF()
        {
            Task.Factory.StartNew(() =>
            {
                //First, discard multiple call to this function (only two calls are available)
                lock (m_isTFUpdateLock)
                {
                    if (m_waitToUpdateTF)
                    {
                        Debug.Log("Already waiting for TF");
                        return;
                    }
                    else
                    {
                        m_waitToUpdateTF = true;
                    }
                }

                //The wait to update the TF
                lock (m_updateTFLock)
                {
                    //Another one can wait to update the TF if it wants (max: two parallel call, one pending, one executing)
                    lock (m_isTFUpdateLock)
                        m_waitToUpdateTF = false;

                    TransferFunction tf = null;
                    lock (m_sd)
                    {
                        if (m_sd.Visibility == SubDatasetVisibility.GONE)
                        {
                            return;
                        }
                        if (m_sd.TransferFunction == null)
                        {
                            return;
                        }
                        tf = (TransferFunction)m_sd.TransferFunction.Clone();
                    }

                    Debug.Log("Updating TF...");

                    byte[] colors = ComputeTFColor(tf);
                    lock (this)
                    {
                        m_colors = colors;
                    }
                }
            });
        }
Example #2
0
        public override bool Equals(object obj)
        {
            if (obj == null)
            {
                return(false);
            }

            if (obj is TransferFunction)
            {
                TransferFunction tf = obj as TransferFunction;
                return(tf.ColorMode == ColorMode && tf.Timestep == Timestep &&
                       tf.MinClipping == MinClipping && tf.MaxClipping == MaxClipping);
            }
            return(false);
        }
Example #3
0
        private void UpdateTF_Thread()
        {
            //First, discard multiple call to this function (only two calls are available)
            lock (m_isTFUpdateLock)
            {
                if (m_waitToUpdateTF)
                {
                    Debug.Log("Already waiting for TF");
                    return;
                }
                else
                {
                    m_waitToUpdateTF = true;
                }
            }

            //The wait to update the TF
            lock (m_updateTFLock)
            {
                //Another one can wait to update the TF if it wants (max: two parallel call, one pending, one executing)
                lock (m_isTFUpdateLock)
                    m_waitToUpdateTF = false;

                TransferFunction tf = null;
                lock (m_subDataset)
                {
                    if (m_subDataset.Visibility == SubDatasetVisibility.GONE)
                    {
                        return;
                    }

                    if (m_subDataset.TransferFunction == null)
                    {
                        return;
                    }

                    tf = (TransferFunction)m_subDataset.TransferFunction.Clone();
                }

                short[] color = ComputeTFColor(tf);
                m_subDataset.TFComputation = color;
            }
        }
Example #4
0
 public virtual void OnTransferFunctionChange(SubDataset dataset, TransferFunction tf)
 {
 }
Example #5
0
 public override void OnTransferFunctionChange(SubDataset dataset, TransferFunction tf)
 {
     base.OnTransferFunctionChange(dataset, tf);
     UpdateTF();
 }
Example #6
0
        private byte[] ComputeTFColor(TransferFunction tf)
        {
            int hasGradient = (tf.HasGradient() ? 1 : 0);

            if (m_dataset.IsLoaded == false || tf == null || tf.GetDimension() - hasGradient > m_dataset.PointFieldDescs.Count ||
                (m_sd.OwnerID != -1 && m_sd.OwnerID != m_dataProvider.GetHeadsetID())) //Not a public subdataset
            {
                return(null);
            }

            else
            {
                unsafe
                {
                    int[] indices = new int[m_dataset.PointFieldDescs.Count];
                    for (int i = 0; i < indices.Length; i++)
                    {
                        indices[i] = i;
                    }

                    Datasets.Gradient gradient = m_dataset.GetGradient(indices);

                    byte[] colors = new byte[4 * m_dataset.NbPoints]; //RGBA colors;

                    List <PointFieldDescriptor> ptDescs = m_dataset.PointFieldDescs;

                    Parallel.For(0, m_dataset.NbPoints,
                                 i =>
                    {
                        fixed(byte *pcolors = colors)
                        {
                            float[] partialRes = new float[indices.Length + hasGradient];

                            if (m_sd.EnableVolumetricMask && !m_sd.GetVolumetricMaskAt((int)i))
                            {
                                pcolors[4 * i + 3] = 0;
                                return;
                            }

                            //Determine transfer function coordinates
                            for (int l = 0; l < ptDescs.Count; l++)
                            {
                                int ids = indices[l];
                                if (ptDescs[ids].NbValuesPerTuple == 1)
                                {
                                    partialRes[ids] = (ptDescs[ids].Value[0].ReadAsFloat((ulong)i) - ptDescs[ids].MinVal) / (ptDescs[ids].MaxVal - ptDescs[ids].MinVal);
                                }
                                else
                                {
                                    partialRes[ids] = (ptDescs[ids].ReadMagnitude((ulong)i, 0) - ptDescs[ids].MinVal) / (ptDescs[ids].MaxVal - ptDescs[ids].MinVal);
                                }
                            }

                            if (tf.HasGradient())
                            {
                                if (gradient != null)
                                {
                                    partialRes[partialRes.Length - 1] = gradient.Values[0][(ulong)i];   //In case we need the gradient
                                }
                                else
                                {
                                    partialRes[partialRes.Length - 1] = 0.0f;
                                }
                            }

                            Color c = tf.ComputeColor(partialRes);

                            pcolors[4 * i + 0] = (byte)(c.r * 255);
                            pcolors[4 * i + 1] = (byte)(c.g * 255);
                            pcolors[4 * i + 2] = (byte)(c.b * 255);
                            pcolors[4 * i + 3] = (byte)(255);
                        }
                    });
                    return(colors);
                }
            }
        }
Example #7
0
 public MergeTF(TransferFunction tf1, TransferFunction tf2, float t = 0.0f) : base(tf1.ColorMode)
 {
     m_tf1 = tf1.Clone();
     m_tf2 = tf2.Clone();
     m_t   = t;
 }
Example #8
0
 /// <summary>
 /// Constructor. The texture is created but not initialized. Use ComputeTexture to do so
 /// </summary>
 /// <param name="tf">The Transfer Function to use</param>
 /// <param name="textureDim">The texture dimension wanted</param>
 /// <param name="mode">The ColorMode to apply</param>
 public TFTexture(TransferFunction tf, Vector2Int textureDim)
 {
     m_tf         = tf;
     m_dimensions = textureDim;
 }
Example #9
0
 public void OnTransferFunctionChange(SubDataset dataset, TransferFunction tf)
 {
     UpdateTF();
 }
Example #10
0
        private short[] ComputeTFColor(TransferFunction tf)
        {
            VTKDataset vtk         = (VTKDataset)m_subDataset.Parent;
            int        hasGradient = (tf.HasGradient() ? 1 : 0);

            if (vtk.IsLoaded == false || tf == null || tf.GetDimension() - hasGradient > vtk.PointFieldDescs.Count ||
                (m_subDataset.OwnerID != -1 && m_subDataset.OwnerID != m_dataProvider.GetHeadsetID())) //Not a public subdataset
            {
                return(null);
            }

            int t1 = (int)Math.Floor(tf.Timestep);
            int t2 = (int)Math.Ceiling(tf.Timestep);

            int[] times = new int[] { t1, t2 };

            unsafe
            {
                int[] indices = new int[vtk.PointFieldDescs.Count];
                for (int i = 0; i < indices.Length; i++)
                {
                    indices[i] = i;
                }

                Datasets.Gradient gradient = vtk.GetGradient(indices);
                short[]           colors   = new short[m_dimensions.x * m_dimensions.y * m_dimensions.z]; //short because RGBA4444 == 2 bytes -> short
                float             frac     = tf.Timestep - (float)Math.Truncate(tf.Timestep);

                List <PointFieldDescriptor> ptDescs = m_subDataset.Parent.PointFieldDescs;

                Parallel.For(0, m_dimensions.z, new ParallelOptions {
                    MaxDegreeOfParallelism = 8
                },
                             (k, state) =>
                {
                    float[] partialResT1 = new float[indices.Length + hasGradient];
                    float[] partialResT2 = new float[indices.Length + hasGradient];

                    fixed(short *pcolors = colors)
                    {
                        //int maxOldK = Math.Max(10 * (curK + 1), m_dimensions.z);
                        //for(int k = 10*curK; k < maxOldK; k++)
                        {
                            UInt64 ind      = (UInt64)(k * m_dimensions.x * m_dimensions.y);
                            UInt64 readIntK = (UInt64)(m_descPts.Size[0] * m_descPts.Size[1] * (k * m_descPts.Size[2] / m_dimensions.z));
                            for (int j = 0; j < m_dimensions.y; j++)
                            {
                                //Pre compute the indice up to J--K coordinate
                                UInt64 readIntJK = (UInt64)(m_descPts.Size[0] * (j * m_descPts.Size[1] / m_dimensions.y)) + readIntK;

                                for (int i = 0; i < m_dimensions.x; i++)
                                {
                                    UInt64 readInd = (UInt64)(i * m_descPts.Size[0] / m_dimensions.x) + readIntJK;

                                    if (vtk.MaskValue != null && ((byte *)(vtk.MaskValue.Value))[readInd] == 0 ||
                                        (m_subDataset.EnableVolumetricMask && m_subDataset.GetVolumetricMaskAt((int)readInd) == false))
                                    {
                                        pcolors[ind] = 0;
                                    }
                                    else
                                    {
                                        float[][] partialRes = new float[][] { partialResT1, partialResT2 };

                                        for (int p = 0; p < 2; p++)
                                        {
                                            //Determine transfer function coordinates
                                            for (int l = 0; l < indices.Length; l++)
                                            {
                                                int ids = indices[l];
                                                if (ptDescs[ids].NbValuesPerTuple == 1)
                                                {
                                                    partialRes[p][ids] = (ptDescs[ids].Value[times[p]].ReadAsFloat(readInd) - ptDescs[ids].MinVal) / (ptDescs[ids].MaxVal - ptDescs[ids].MinVal);
                                                }
                                                else
                                                {
                                                    partialRes[p][ids] = (ptDescs[ids].ReadMagnitude(readInd, times[p]) - ptDescs[ids].MinVal) / (ptDescs[ids].MaxVal - ptDescs[ids].MinVal);
                                                }
                                            }

                                            if (tf.HasGradient())
                                            {
                                                if (gradient != null)
                                                {
                                                    partialRes[p][partialRes[p].Length - 1] = gradient.Values[times[p]][readInd]; //In case we need the gradient
                                                }
                                                else
                                                {
                                                    partialRes[p][partialRes[p].Length - 1] = 0.0f;
                                                }
                                            }
                                        }

                                        //Linear interpolation
                                        Color c = (1.0f - frac) * tf.ComputeColor(partialResT1) + frac * tf.ComputeColor(partialResT2);
                                        float a = (1.0f - frac) * tf.ComputeAlpha(partialResT1) + frac * tf.ComputeAlpha(partialResT2);

                                        byte r = (byte)(16 * c.r);
                                        if (r > 15)
                                        {
                                            r = 15;
                                        }
                                        byte g = (byte)(16 * c.g);
                                        if (g > 15)
                                        {
                                            g = 15;
                                        }
                                        byte b = (byte)(16 * c.b);
                                        if (b > 15)
                                        {
                                            b = 15;
                                        }
                                        byte _a = (byte)(16 * a);
                                        if (_a > 15)
                                        {
                                            _a = 15;
                                        }

                                        pcolors[ind] = (short)((r << 12) + (g << 8) + //RGBA4444 color format
                                                               (b << 4) + _a);
                                    }
                                    ind += 1;
                                }
                            }
                        }
                    }
                });
                return(colors);
            }
        }