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>(); }
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); } }