/// <summary> /// Fills the unstructured grid cell buffer. /// </summary> /// <param name="nbCells">Nb cells.</param> /// <param name="ptValues">Point values.</param> /// <param name="cellValues">Cell values.</param> /// <param name="cellTypes">Cell types.</param> /// <param name="buffer">Buffer.</param> /// <param name="destFormat">Destination format.</param> public unsafe void FillUnstructuredGridCellBuffer(UInt32 nbCells, VTKValue ptValues, VTKValue cellValues, VTKValue cellTypes, IntPtr buffer, VTKValueFormat destFormat = VTKValueFormat.VTK_NO_VALUE_FORMAT) { unsafe { VTKInterop.VTKParser_fillUnstructuredGridCellBuffer(m_parser, nbCells, ptValues.Value, (Int32 *)cellValues.Value, (Int32 *)cellTypes.Value, buffer, destFormat); } }
/// <summary> /// Parse all the Unstructured Grid Points available in this dataset. /// Use FillUnstructuredGridCellBuffer for getting triangle composition of these cells /// </summary> /// <returns>A VTKValue of these points.</returns> public VTKValue ParseAllUnstructuredGridPoints() { VTKValue val = new VTKValue(); VTKPointPositions pos = VTKInterop.VTKParser_getUnstructuredGridPointDescriptor(m_parser); val.Value = VTKInterop.VTKParser_parseAllUnstructuredGridPoints(m_parser); val.NbValues = pos.NbPoints * 3; return(val); }
/// <summary> /// Get the concrete Value of a Field Value /// </summary> /// <returns>The VTK value.</returns> /// <param name="val">Value.</param> public VTKValue ParseAllFieldValues(VTKFieldValue fieldVal) { VTKValue val = new VTKValue(); val.NbValues = fieldVal.NbTuples * fieldVal.NbValuesPerTuple; val.Value = VTKInterop.VTKParser_parseAllFieldValues(m_parser, fieldVal.NativePtr); val.Format = fieldVal.Format; return(val); }
/// <summary> /// Get the values of Cell Types for understanding how to merge the points described in ParseAllUnstructuredGridCellsComposition. /// Use FillUnstructuredGridCellBuffer for getting triangle composition of these cells /// </summary> /// <returns>A VTKValue of all the cell types of this dataset. Format : VTK_INT</returns> public VTKValue ParseAllUnstructuredGridCellTypesDescriptor() { VTKCellTypes desc = VTKInterop.VTKParser_getUnstructuredGridCellTypesDescriptor(m_parser); VTKValue res = new VTKValue(); res.Format = VTKValueFormat.VTK_INT; unsafe { res.Value = VTKInterop.VTKParser_parseAllUnstructuredGridCellTypes(m_parser); } res.NbValues = desc.NbCells; return(res); }
/// <summary> /// Get the values of Cell composition for unstructured grid. Use TODO for getting triangle composition of these cells /// </summary> /// <returns>A VTKValue of the cell composition. Format : VTK_INT</returns> public VTKValue ParseAllUnstructuredGridCellsComposition() { VTKCells desc = VTKInterop.VTKParser_getUnstructuredGridCellDescriptor(m_parser); VTKValue res = new VTKValue(); unsafe { res.Value = VTKInterop.VTKParser_parseAllUnstructuredGridCellsComposition(m_parser); } res.NbValues = desc.WholeSize; res.Format = VTKValueFormat.VTK_INT; return(res); }
/// <summary> /// Gets the cell construction descriptor. /// </summary> /// <returns>The cell construction descriptor.</returns> /// <param name="nbCells">Nb cells.</param> /// <param name="cellValues">Cell values.</param> /// <param name="cellTypes">Cell types.</param> public static VTKCellConstruction GetCellConstructionDescriptor(UInt32 nbCells, VTKValue cellValues, VTKValue cellTypes) { unsafe { return(VTKInterop.VTKParser_getCellConstructionDescriptor(nbCells, (Int32 *)cellValues.Value, (Int32 *)cellTypes.Value)); } }
void Start() { //Parse the VTK object m_parser = new VTKParser($"{Application.streamingAssetsPath}/{FilePath}"); if (!m_parser.Parse()) { Debug.Log("Error at parsing the ocean dataset"); return; } //Check if the type is structured points //If so, create the structured points ! if (m_parser.GetDatasetType() == VTKDatasetType.VTK_STRUCTURED_POINTS) { m_oceanGrid = GameObject.Instantiate(StructuredGrid); unsafe { //Check if the first attribute is a char. If so, used these as a mask byte *mask = null; List <VTKFieldValue> fieldDesc = m_parser.GetPointFieldValueDescriptors(); foreach (var f in fieldDesc) { //TODO use Unity to give that value name (this is the mask value name) if (f.Name == "vtkValidPointMask" && f.Format == VTKValueFormat.VTK_CHAR) { VTKValue val = m_parser.ParseAllFieldValues(f); m_maskValue = val; mask = (byte *)(val.Value); } } if (!m_oceanGrid.Init(m_parser, mask)) { return; } } Vector3 size = m_oceanGrid.MaxMeshPos - m_oceanGrid.MinMeshPos; //Generate the small multiples m_smallMultiples = new List <VTKUnitySmallMultiple>(); m_textSMMeshes = new List <TextMesh>(); m_smallMultiples.Add(m_oceanGrid.CreatePointFieldSmallMultiple(2)); m_smallMultiples.Add(m_oceanGrid.CreatePointFieldSmallMultiple(3)); m_smallMultiples.Add(m_oceanGrid.CreatePointFieldSmallMultiple(4)); //Place them correctly and associate the text for (int i = 0; i < m_smallMultiples.Count; i++) { //Small multiple var c = m_smallMultiples[i]; c.transform.parent = this.transform; c.transform.localPosition = new Vector3(2.5f * i, 0, 0); c.transform.localScale = new Vector3(1.0f, 1.0f, 1.0f); //c.SphereEnabled = true; //c.PlaneEnabled = true; c.transform.localRotation = Quaternion.Euler(0.0f, 180.0f, 0.0f); //Text TextMesh smText = Instantiate(SmallMultipleTextProperty); m_textSMMeshes.Add(smText); smText.text = m_oceanGrid.GetPointFieldName((UInt32)i + 2); smText.transform.parent = c.transform; smText.transform.localPosition = new Vector3(0.0f, size.y + 0.1f, 0.0f); smText.transform.localScale = new Vector3(0.1f, 0.1f, 0.1f); smText.transform.localRotation = new Quaternion(0.0f, 0.0f, 0.0f, 1.0f); } } }
/// <summary> /// Initialize the small multiple from point field data /// </summary> /// <param name="parser">The VTK Parser</param> /// <param name="mesh">The mesh to display</param> /// <param name="uvID">The ID where to put the color data</param> /// <param name="valueID">The ID of the VTKFieldPointValue</param> /// <param name="offset">The offset along each axis to apply : pos = x*offset.x + y*offset.y + z*offset.z</param> /// <param name="density">The density in use</param> /// <param name="mask">The mask to apply along each point</param> /// <returns></returns> public unsafe bool InitFromPointField(VTKParser parser, Mesh mesh, Int32 uvID, Int32 valueID, Vector3Int offset, Vector3Int density, byte *mask) { m_material = new Material(ColorMaterial); m_values = new float[density.x * density.y * density.z]; //Check the ID if (uvID > 7) { Debug.Log("The uvID must be between 0 to 7. This is a limitation of Unity for working within a common mesh..."); return(false); } m_mesh = mesh; VTKStructuredPoints descPts = parser.GetStructuredPointsDescriptor(); //Determine the maximum and minimum positions Vector3 minModelPos = new Vector3((float)(-descPts.Size[0] / 2.0 * descPts.Spacing[0]), (float)(-descPts.Size[1] / 2.0 * descPts.Spacing[1]), (float)(-descPts.Size[2] / 2.0 * descPts.Spacing[2])); Vector3 maxModelPos = -minModelPos; //The value buffer List <VTKFieldValue> fieldDesc = parser.GetPointFieldValueDescriptors(); if (fieldDesc.Count < valueID) { Debug.Log("No value to display"); return(false); } VTKValue val = parser.ParseAllFieldValues(fieldDesc[valueID]); List <Vector4> colors = new List <Vector4>((int)(density.x * density.y * density.z)); //Determine the minimum and maximum value and their position m_maxVal = float.MinValue; m_minVal = float.MaxValue; Vector3 minLoc = new Vector3(); Vector3 maxLoc = new Vector3(); for (UInt32 i = 0; i < val.NbValues; i++) { if (mask != null && mask[i] == 0) { continue; } float v = (float)val.ReadAsDouble(i * fieldDesc[valueID].NbValuesPerTuple); if (m_maxVal < v) { m_maxVal = v; maxLoc = new Vector3(i % descPts.Size[0], (i / descPts.Size[0]) % descPts.Size[1], i / (descPts.Size[0] * descPts.Size[1])); } if (m_minVal > v) { m_minVal = v; minLoc = new Vector3(i % descPts.Size[0], (i / descPts.Size[0]) % descPts.Size[1], i / (descPts.Size[0] * descPts.Size[1])); } } //Normalize the location (between 0.0 and 1.0 for the most "long" axis) Vector3[] vec = new Vector3[2] { maxLoc, minLoc }; Vector3 modelDist = maxModelPos - minModelPos; float maxModelDist = Math.Max(modelDist.x, Math.Max(modelDist.y, modelDist.z)); for (int i = 0; i < vec.Length; i++) { Vector3 l = vec[i]; l = (new Vector3((float)(l.x * descPts.Spacing[0]), (float)(l.y * descPts.Spacing[1]), (float)(l.z * descPts.Spacing[2])) + minModelPos) / maxModelDist; vec[i] = l; } Debug.Log($"Min : {m_minVal} Max : {m_maxVal}"); //Fill the color array maxLoc = vec[0]; minLoc = vec[1]; UInt64 colorValueOff = 0; for (UInt32 k = 0; k < density.z; k++) { for (UInt32 j = 0; j < density.y; j++) { for (UInt32 i = 0; i < density.x; i++, colorValueOff++) { UInt64 fieldOff = (UInt64)(i * offset.x + j * offset.y + k * offset.z); //Check the mask if (mask != null && *(mask + fieldOff) == 0) { colors.Add(new Vector4(0.0f, 0.0f, 0.0f, 0.0f)); m_values[colorValueOff] = m_minVal; continue; } float c = val.ReadAsFloat(fieldOff * fieldDesc[valueID].NbValuesPerTuple); m_values[colorValueOff] = c; c = (float)((c - m_minVal) / (m_maxVal - m_minVal)); //LAB color space (warm - cold) Color?col = null; if (c < 0.5) { col = LABColor.Lerp(coldColor, whiteColor, 2.0f * c).ToXYZ().ToRGB(); } else { col = LABColor.Lerp(whiteColor, warmColor, 2.0f * (c - 0.5f)).ToXYZ().ToRGB(); } colors.Add(new Vector4(col.Value.r, col.Value.g, col.Value.b, 1.0f)); } } } //Update the mesh / material m_mesh.SetUVs(uvID, colors); m_mesh.UploadMeshData(false); m_colorID = uvID; for (int i = 0; i < 8; i++) { if (i != m_colorID) { m_material.DisableKeyword($"TEXCOORD{i}_ON"); } } m_material.EnableKeyword($"TEXCOORD{m_colorID}_ON"); PlaneEnabled = false; SphereEnabled = false; CreateGameObjects(vec); return(true); }