Esempio n. 1
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);
                }
            }
        }
Esempio n. 2
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);
            }
        }