Exemplo n.º 1
0
        public unsafe VTKUnityStructuredGrid(VTKDataset vtkDataset, UInt32 desiredDensity, IDataProvider dataProvider)
        {
            m_dataset        = vtkDataset;
            m_desiredDensity = desiredDensity;
            m_dataProvider   = dataProvider;

            VTKParser parser = m_dataset.Parser;

            if (parser.GetDatasetType() != VTKDatasetType.VTK_STRUCTURED_POINTS)
            {
                Debug.Log("Error: The dataset should be a structured points dataset");
                return;
            }

            //Get the points and modify the points / normals buffer
            m_ptsDesc = parser.GetStructuredPointsDescriptor();

            //Determine the new dimension and spacing
            m_dimensions = GetDisplayableSize();
            float maxAxis = (float)Math.Max(m_ptsDesc.Spacing[0] * m_ptsDesc.Size[0],
                                            Math.Max(m_ptsDesc.Spacing[1] * m_ptsDesc.Size[1],
                                                     m_ptsDesc.Spacing[2] * m_ptsDesc.Size[2]));

            for (int i = 0; i < 3; i++)
            {
                m_spacing[i] = (float)(m_ptsDesc.Size[i] * m_ptsDesc.Spacing[i] / m_dimensions[i] / maxAxis);
            }

            //Small multiples array
            m_smallMultiples = new List <VTKUnitySmallMultiple>();
        }
Exemplo n.º 2
0
        /// <summary>
        /// Initialize the small multiple
        /// </summary>
        /// <param name="parser">The VTK Parser</param>
        /// <param name="subDataset">The SubDataset bound to this VTK view</param>
        /// <param name="dimensions">The dimensions in use</param>
        /// <param name="dataProvider">The application data provider (a.k.a, Main)</param>
        /// <returns></returns>
        public unsafe bool Init(VTKParser parser, SubDataset subDataset, Vector3Int dimensions, IDataProvider dataProvider)
        {
            subDataset.AddListener(this);
            m_subDataset   = subDataset;
            m_dataProvider = dataProvider;

            //Copy the variables
            m_dimensions = dimensions;

            VTKStructuredPoints descPts = parser.GetStructuredPointsDescriptor();

            m_descPts = descPts;

            float maxAxis = (float)Math.Max(descPts.Spacing[0] * m_dimensions[0],
                                            Math.Max(descPts.Spacing[1] * m_dimensions[1],
                                                     descPts.Spacing[2] * m_dimensions[2]));

            m_spacing = new Vector3();
            for (int i = 0; i < 3; i++)
            {
                m_spacing[i] = (float)(descPts.Spacing[i] / maxAxis);
            }

            UpdateTF();

            return(true);
        }
Exemplo n.º 3
0
        /// <summary>
        /// get the displayable size of the vector field. Indeed, due to hardware limitation, we cannot display all the vector field at once
        /// </summary>
        /// <returns>The vector field size displayable</returns>
        private Vector3Int GetDisplayableSize()
        {
            VTKStructuredPoints m_ptsDesc = m_dataset.Parser.GetStructuredPointsDescriptor();

            if (m_ptsDesc.Size[0] == 0 || m_ptsDesc.Size[1] == 0 || m_ptsDesc.Size[2] == 0)
            {
                return(new Vector3Int(0, 0, 0));
            }

            int maxRatio = (int)GetFieldSizeDiviser();

            return(new Vector3Int((int)m_ptsDesc.Size[0] / maxRatio, (int)m_ptsDesc.Size[1] / maxRatio, (int)m_ptsDesc.Size[2] / maxRatio));
        }
Exemplo n.º 4
0
        /// <summary>
        /// Get the size diviser used for the displayability of the dataset (structured grid)
        /// </summary>
        /// <returns>The field diviser applied along all axis</returns>
        public UInt32 GetFieldSizeDiviser()
        {
            VTKStructuredPoints m_ptsDesc = m_dataset.Parser.GetStructuredPointsDescriptor();

            if (DesiredDensity == 0)
            {
                return(1);
            }

            UInt32 x = (m_ptsDesc.Size[0] + DesiredDensity - 1) / DesiredDensity;
            UInt32 y = (m_ptsDesc.Size[1] + DesiredDensity - 1) / DesiredDensity;
            UInt32 z = (m_ptsDesc.Size[2] + DesiredDensity - 1) / DesiredDensity;

            return(Math.Max(1, Math.Max(Math.Max(x, y), z)));
        }
Exemplo n.º 5
0
    static void Main(String[] argv)
    {
        if (argv.Length < 1)
        {
            Console.WriteLine("Needs the path to the dataset");
            return;
        }

        VTKParser parser = new VTKParser(argv[0]);

        if (!parser.Parse())
        {
            Console.WriteLine($"Fail to parse the file {argv[0]}");
            return;
        }

        if (parser.GetDatasetType() == VTKDatasetType.VTK_UNSTRUCTURED_GRID)
        {
            Console.WriteLine("Unstructured grid");
            return;
        }
        else if (parser.GetDatasetType() == VTKDatasetType.VTK_STRUCTURED_POINTS)
        {
            Console.WriteLine("Structured points");
            VTKStructuredPoints pts = parser.GetStructuredPointsDescriptor();
            Console.WriteLine($"Structured points : dimensions {pts.Size[0]}, {pts.Size[1]}, {pts.Size[2]}");
            Console.WriteLine($"Structured points : spacing    {pts.Spacing[0]:F4}, {pts.Spacing[1]:F4}, {pts.Spacing[2]:F4}");
            Console.WriteLine($"Structured points : origin     {pts.Origin[0]:F4},  {pts.Origin[1]:F4},  {pts.Origin[2]:F4}");

            List <VTKFieldValue> fieldDesc = parser.GetPointFieldValueDescriptors();
            if (fieldDesc.Count > 0)
            {
                foreach (var f in fieldDesc)
                {
                    Console.WriteLine($"Found {f.Name} with {f.NbTuples} values");
                }
            }
            else
            {
                Console.WriteLine("No value found...");
            }

            return;
        }
    }
Exemplo n.º 6
0
        public override uint GetNbSpatialValues()
        {
            VTKStructuredPoints p = Parser.GetStructuredPointsDescriptor();

            return(p.Size[0] * p.Size[1] * p.Size[2]);
        }
Exemplo n.º 7
0
        protected override Gradient ComputeGradient(int[] indices)
        {
            if (indices.Count() == 0)
            {
                return(null);
            }

            Gradient gradient = new Gradient(indices);

            for (int t = 0; t < m_nbTimesteps; t++)
            {
                VTKStructuredPoints ptsDesc = Parser.GetStructuredPointsDescriptor();
                float[]             grad    = new float[ptsDesc.Size[0] * ptsDesc.Size[1] * ptsDesc.Size[2]];
                float maxVal = 0;

                object lockObject = new object();

                ///////////////////////////////
                ///Compute "Inside" Gradient///
                ///////////////////////////////

                //Multi dimensionnal gradient computation, based on
                //Joe Kniss, Gordon Kindlmann, and Charles Hansen. 2002. Multidimensional Transfer Functions for Interactive Volume Rendering. IEEE Transactions on Visualization and Computer Graphics 8, 3 (July 2002), 270-285. DOI: https://doi.org/10.1109/TVCG.2002.1021579
                if (indices.Count() > 1)
                {
                    Parallel.For(1, ptsDesc.Size[2] - 1,
                                 () => new { maxGrad = new float[1] {
                                                 float.MinValue
                                             }, df = new float[3 * indices.Count()], localGrad = new float[3], g = new float[9] },
                                 (k, loopState, partialRes) =>
                    {
                        for (UInt32 j = 1; j < ptsDesc.Size[1] - 1; j++)
                        {
                            for (UInt32 i = 1; i < ptsDesc.Size[0] - 1; i++)
                            {
                                //Indices
                                UInt64 ind = (UInt64)(i + j * ptsDesc.Size[0] + k * ptsDesc.Size[1] * ptsDesc.Size[0]);

                                //Read mask
                                unsafe
                                {
                                    if (m_mask != null && ((byte *)m_mask.Value)[ind] == 0)
                                    {
                                        grad[ind] = 0;
                                        continue;
                                    }
                                }

                                UInt64 indX1 = ind - 1;
                                UInt64 indX2 = ind + 1;
                                UInt64 indY1 = ind - (UInt64)(ptsDesc.Size[0]);
                                UInt64 indY2 = ind + (UInt64)(ptsDesc.Size[0]);
                                UInt64 indZ1 = ind - (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);
                                UInt64 indZ2 = ind + (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);

                                //Start computing the Df matrix.
                                for (int l = 0; l < indices.Count(); l++)
                                {
                                    int ids = indices[l];
                                    if (m_ptFieldDescs[ids].NbValuesPerTuple == 1)
                                    {
                                        partialRes.localGrad[0] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indX2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indX1)) / (2.0f * (float)ptsDesc.Spacing[0]);
                                        partialRes.localGrad[1] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indY2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indY1)) / (2.0f * (float)ptsDesc.Spacing[1]);
                                        partialRes.localGrad[2] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indZ2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indZ1)) / (2.0f * (float)ptsDesc.Spacing[2]);
                                        partialRes.localGrad[2] = 0.0f;
                                    }
                                    else
                                    {
                                        partialRes.localGrad[0] = (m_ptFieldDescs[ids].ReadMagnitude(indX2, t) - m_ptFieldDescs[ids].ReadMagnitude(indX1, t)) / (2.0f * (float)ptsDesc.Spacing[0]);
                                        partialRes.localGrad[1] = (m_ptFieldDescs[ids].ReadMagnitude(indY2, t) - m_ptFieldDescs[ids].ReadMagnitude(indY1, t)) / (2.0f * (float)ptsDesc.Spacing[1]);
                                        partialRes.localGrad[2] = (m_ptFieldDescs[ids].ReadMagnitude(indZ2, t) - m_ptFieldDescs[ids].ReadMagnitude(indZ1, t)) / (2.0f * (float)ptsDesc.Spacing[2]);
                                        partialRes.localGrad[2] = 0.0f;
                                    }

                                    //Fill df
                                    for (int ii = 0; ii < 3; ii++)
                                    {
                                        partialRes.df[3 * l + ii] = partialRes.localGrad[ii] / (m_ptFieldDescs[ids].MaxVal - m_ptFieldDescs[ids].MinVal);
                                    }
                                }

                                //Compute g = Df^T * Df
                                for (UInt32 l = 0; l < 9; l++)
                                {
                                    partialRes.g[l] = 0;
                                }
                                for (UInt32 n = 0; n < indices.Count(); n++)
                                {
                                    for (UInt32 l = 0; l < 3; l++)
                                    {
                                        for (UInt32 m = 0; m < 3; m++)
                                        {
                                            partialRes.g[3 * l + m] += partialRes.df[3 * n + l] * partialRes.df[3 * n + m];
                                        }
                                    }
                                }

                                //Grad == L2 norm of g.
                                //Taking sqrt(sum_{k=0}^9 g[k]*g[k]) is a good approximation based on Kniss et al. paper
                                float gradMag = 0;
                                for (UInt32 l = 0; l < 9; l++)
                                {
                                    gradMag += partialRes.g[l] * partialRes.g[l];
                                }

                                if (!float.IsNaN(gradMag))
                                {
                                    gradMag               = (float)Math.Sqrt(gradMag);
                                    grad[ind]             = gradMag;
                                    partialRes.maxGrad[0] = Math.Max(partialRes.maxGrad[0], gradMag);
                                }
                                else
                                {
                                    grad[ind] = 0;
                                }
                            }
                        }
                        return(partialRes);
                    },
                                 (partialRes) =>
                    {
                        lock (lockObject)
                        {
                            maxVal = Math.Max(maxVal, partialRes.maxGrad[0]);
                        }
                    });
                }

                //1D gradient computation
                else if (m_ptFieldDescs[indices[0]].NbValuesPerTuple == 1)
                {
                    int ids = indices[0];
                    Parallel.For(1, ptsDesc.Size[2] - 1,
                                 () => new { maxGrad = new float[1] {
                                                 0
                                             }, localGrad = new float[3] },
                                 (k, loopState, partialRes) =>
                    {
                        for (UInt32 j = 1; j < ptsDesc.Size[1] - 1; j++)
                        {
                            for (UInt32 i = 1; i < ptsDesc.Size[0] - 1; i++)
                            {
                                //Indices
                                UInt64 ind = (UInt64)(i + j * ptsDesc.Size[0] + k * ptsDesc.Size[1] * ptsDesc.Size[0]);

                                //Read mask
                                unsafe
                                {
                                    if (m_mask != null && ((byte *)m_mask.Value)[ind] == 0)
                                    {
                                        grad[ind] = 0;
                                        continue;
                                    }
                                }

                                UInt64 indX1 = ind - 1;
                                UInt64 indX2 = ind + 1;
                                UInt64 indY1 = ind - (UInt64)(ptsDesc.Size[0]);
                                UInt64 indY2 = ind + (UInt64)(ptsDesc.Size[0]);
                                UInt64 indZ1 = ind - (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);
                                UInt64 indZ2 = ind + (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);

                                partialRes.localGrad[0] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indX2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indX1)) / (2.0f * (float)ptsDesc.Spacing[0]);
                                partialRes.localGrad[1] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indY2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indY1)) / (2.0f * (float)ptsDesc.Spacing[1]);
                                partialRes.localGrad[2] = (m_ptFieldDescs[ids].Value[t].ReadAsFloat(indZ2) - m_ptFieldDescs[ids].Value[t].ReadAsFloat(indZ1)) / (2.0f * (float)ptsDesc.Spacing[2]);
                                partialRes.localGrad[2] = 0.0f;

                                float gradMag = 0;
                                for (UInt32 l = 0; l < 3; l++)
                                {
                                    partialRes.localGrad[l] /= (m_ptFieldDescs[ids].MaxVal - m_ptFieldDescs[ids].MinVal);
                                    gradMag += partialRes.localGrad[l] * partialRes.localGrad[l];
                                }

                                if (!float.IsNaN(gradMag))
                                {
                                    gradMag               = (float)Math.Sqrt(gradMag);
                                    grad[ind]             = gradMag;
                                    partialRes.maxGrad[0] = Math.Max(partialRes.maxGrad[0], gradMag);
                                }
                                else
                                {
                                    grad[ind] = 0;
                                }
                            }
                        }
                        return(partialRes);
                    },
                                 (partialRes) =>
                    {
                        lock (lockObject)
                        {
                            maxVal = Math.Max(maxVal, partialRes.maxGrad[0]);
                        }
                    });
                }

                else
                {
                    int ids = indices[0];

                    Parallel.For(1, ptsDesc.Size[2] - 1,
                                 () => new { maxGrad = new float[1] {
                                                 0
                                             }, localGrad = new float[3] },
                                 (k, loopState, partialRes) =>
                    {
                        for (UInt32 j = 1; j < ptsDesc.Size[1] - 1; j++)
                        {
                            for (UInt32 i = 1; i < ptsDesc.Size[0] - 1; i++)
                            {
                                //Indices
                                UInt64 ind = (UInt64)(i + j * ptsDesc.Size[0] + k * ptsDesc.Size[1] * ptsDesc.Size[0]);

                                //Read mask
                                unsafe
                                {
                                    if (m_mask != null && ((byte *)m_mask.Value)[ind] == 0)
                                    {
                                        grad[ind] = 0;
                                        continue;
                                    }
                                }

                                UInt64 indX1 = ind - 1;
                                UInt64 indX2 = ind + 1;
                                UInt64 indY1 = ind - (UInt64)(ptsDesc.Size[0]);
                                UInt64 indY2 = ind + (UInt64)(ptsDesc.Size[0]);
                                UInt64 indZ1 = ind - (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);
                                UInt64 indZ2 = ind + (UInt64)(ptsDesc.Size[1] * ptsDesc.Size[0]);

                                partialRes.localGrad[0] = (m_ptFieldDescs[ids].ReadMagnitude(indX2, t) - m_ptFieldDescs[ids].ReadMagnitude(indX1, t)) / (2.0f * (float)ptsDesc.Spacing[0]);
                                partialRes.localGrad[1] = (m_ptFieldDescs[ids].ReadMagnitude(indY2, t) - m_ptFieldDescs[ids].ReadMagnitude(indY1, t)) / (2.0f * (float)ptsDesc.Spacing[1]);
                                partialRes.localGrad[2] = (m_ptFieldDescs[ids].ReadMagnitude(indZ2, t) - m_ptFieldDescs[ids].ReadMagnitude(indZ1, t)) / (2.0f * (float)ptsDesc.Spacing[2]);
                                partialRes.localGrad[2] = 0.0f;

                                float gradMag = 0;
                                for (UInt32 l = 0; l < 3; l++)
                                {
                                    partialRes.localGrad[l] /= (m_ptFieldDescs[ids].MaxVal - m_ptFieldDescs[ids].MinVal);
                                    gradMag += partialRes.localGrad[l] * partialRes.localGrad[l];
                                }


                                if (!float.IsNaN(gradMag))
                                {
                                    gradMag               = (float)Math.Sqrt(gradMag);
                                    grad[ind]             = gradMag;
                                    partialRes.maxGrad[0] = Math.Max(partialRes.maxGrad[0], gradMag);
                                }
                                else
                                {
                                    grad[ind] = 0;
                                }
                            }
                        }
                        return(partialRes);
                    },
                                 (partialRes) =>
                    {
                        lock (lockObject)
                        {
                            maxVal = Math.Max(maxVal, partialRes.maxGrad[0]);
                        }
                    });
                }

                ////////////////////////////////
                //////Set boundaries to 0///////
                ////////////////////////////////
                //When gradient is not computable - default 0.0f
                Parallel.For(0, ptsDesc.Size[1], j =>
                {
                    for (UInt32 i = 0; i < ptsDesc.Size[0]; i++)
                    {
                        UInt64 colorValueOff1 = (UInt64)(i + ptsDesc.Size[0] * j);
                        UInt64 colorValueOff2 = (UInt64)(i + ptsDesc.Size[0] * j + ptsDesc.Size[0] * ptsDesc.Size[1] * (ptsDesc.Size[2] - 1));
                        grad[colorValueOff1]  = grad[colorValueOff2] = 0.0f;
                    }
                });
                Parallel.For(0, ptsDesc.Size[2], k =>
                {
                    for (UInt32 i = 0; i < ptsDesc.Size[0]; i++)
                    {
                        UInt64 colorValueOff1 = (UInt64)(i + ptsDesc.Size[0] * ptsDesc.Size[1] * k);
                        UInt64 colorValueOff2 = (UInt64)(i + ptsDesc.Size[0] * (ptsDesc.Size[1] - 1) + ptsDesc.Size[0] * ptsDesc.Size[1] * k);
                        grad[colorValueOff1]  = grad[colorValueOff2] = 0.0f;
                    }
                });
                Parallel.For(0, ptsDesc.Size[2], k =>
                {
                    for (UInt32 j = 0; j < ptsDesc.Size[1]; j++)
                    {
                        UInt64 colorValueOff1 = (UInt64)(ptsDesc.Size[0] * j + ptsDesc.Size[0] * ptsDesc.Size[1] * k);
                        UInt64 colorValueOff2 = (UInt64)(ptsDesc.Size[0] - 1 + ptsDesc.Size[0] * j + ptsDesc.Size[0] * ptsDesc.Size[1] * k);
                        grad[colorValueOff1]  = grad[colorValueOff2] = 0.0f;
                    }
                });

                gradient.Values.Add(grad);
            }

            return(gradient);
        }