/// <summary> /// Initialize the StructuredGrid representation /// </summary> /// <param name="parser">The VKTParser to use. /// It should not be closed while this object is intented to being modified (e.g adding small multiples)</param> /// <param name="mask">The mask to apply point per point. if mask==null, we do not use it</param> /// <returns></returns> public unsafe bool Init(VTKParser parser, byte *mask = null) { m_parser = parser; m_mask = mask; if (m_parser.GetDatasetType() != VTKDatasetType.VTK_STRUCTURED_POINTS) { Debug.Log("Error: The dataset should be a structured points dataset"); return(false); } //Get the points and modify the points / normals buffer VTKStructuredPoints ptsDesc = m_parser.GetStructuredPointsDescriptor(); Vector3Int density = Density; Vector3[] pts = new Vector3[density.x * density.y * density.z]; //Determine the positions for "normalizing" the object (the biggest axis of the object at "size = 1") Vector3 minPos = new Vector3((float)((density.x / 2) * ptsDesc.Size[0] / density.x * ptsDesc.Spacing[0]), (float)((density.y / 2) * ptsDesc.Size[1] / density.y * ptsDesc.Spacing[1]), (float)((density.z / 2) * ptsDesc.Size[2] / density.z * ptsDesc.Spacing[2])); Vector3 maxPos = new Vector3((float)((density.x - 1 + density.x / 2) * ptsDesc.Size[0] / density.x * ptsDesc.Spacing[0]), (float)((density.y - 1 + density.y / 2) * ptsDesc.Size[1] / density.y * ptsDesc.Spacing[1]), (float)((density.z - 1 + density.z / 2) * ptsDesc.Size[2] / density.z * ptsDesc.Spacing[2])); float maxAxis = Math.Max(maxPos.x - minPos.x, Math.Max(maxPos.y - minPos.y, maxPos.z - minPos.z)); for (int k = 0; k < density.z; k++) { for (int j = 0; j < density.y; j++) { for (int i = 0; i < density.x; i++) { pts[i + density.x * j + density.x * density.y * k] = new Vector3((float)((i - density.x / 2) * ptsDesc.Size[0] / density.x * ptsDesc.Spacing[0]) / maxAxis, (float)((j - density.y / 2) * ptsDesc.Size[1] / density.y * ptsDesc.Spacing[1]) / maxAxis, (float)((k - density.z / 2) * ptsDesc.Size[2] / density.z * ptsDesc.Spacing[2]) / maxAxis); } } } //Store the maximas positions m_minPos = pts[0]; m_maxPos = pts[pts.Length - 1]; //The element buffer Vector3Int offsetMask = new Vector3Int((int)(ptsDesc.Size[0] / density.x), (int)(ptsDesc.Size[1] / density.y * ptsDesc.Size[0]), (int)(ptsDesc.Size[2] / density.z * ptsDesc.Size[1] * ptsDesc.Size[0])); int[] triangles = new int[(density.x - 1) * (density.y - 1) * (density.z - 1) * 36]; for (int k = 0; k < density.z - 1; k++) { for (int j = 0; j < density.y - 1; j++) { for (int i = 0; i < density.x - 1; i++) { int offset = (i + j * (density.x - 1) + k * (density.x - 1) * (density.y - 1)) * 36; //Test the mask //If we are encountering a missing mask, put the triangles to to point "0" (i.e empty triangle) //And go at the end of the loop if (mask != null) { for (int k2 = 0; k2 < 2; k2++) { for (int j2 = 0; j2 < 2; j2++) { for (int i2 = 0; i2 < 2; i2++) { if (*(mask + (i + i2) * offsetMask.x + (j + j2) * offsetMask.y + (k + k2) * offsetMask.z) == 0) { for (int t = 0; t < 36; t++) { triangles[offset + t] = 0; } goto endTriangleLoop; } } } } } //Front triangles[offset] = i + 1 + j * density.x + k * density.x * density.y; triangles[offset + 1] = i + j * density.x + k * density.x * density.y; triangles[offset + 2] = i + 1 + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 3] = i + 1 + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 4] = i + j * density.x + k * density.x * density.y; triangles[offset + 5] = i + (j + 1) * density.x + k * density.x * density.y; //Back triangles[offset + 6] = i + 1 + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 7] = i + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 8] = i + 1 + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 9] = i + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 10] = i + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 11] = i + 1 + (j + 1) * density.x + (k + 1) * density.x * density.y; //Left triangles[offset + 12] = i + j * density.x + k * density.x * density.y; triangles[offset + 13] = i + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 14] = i + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 15] = i + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 16] = i + j * density.x + k * density.x * density.y; triangles[offset + 17] = i + (j + 1) * density.x + (k + 1) * density.x * density.y; //Right triangles[offset + 18] = (i + 1) + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 19] = (i + 1) + j * density.x + k * density.x * density.y; triangles[offset + 20] = (i + 1) + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 21] = (i + 1) + j * density.x + k * density.x * density.y; triangles[offset + 22] = (i + 1) + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 23] = (i + 1) + (j + 1) * density.x + (k + 1) * density.x * density.y; //Top triangles[offset + 24] = (i + 1) + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 25] = i + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 26] = i + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 27] = (i + 1) + (j + 1) * density.x + (k + 1) * density.x * density.y; triangles[offset + 28] = (i + 1) + (j + 1) * density.x + k * density.x * density.y; triangles[offset + 29] = i + (j + 1) * density.x + (k + 1) * density.x * density.y; //Bottom triangles[offset + 30] = (i + 1) + j * density.x + k * density.x * density.y; triangles[offset + 31] = i + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 32] = i + j * density.x + k * density.x * density.y; triangles[offset + 33] = (i + 1) + j * density.x + k * density.x * density.y; triangles[offset + 34] = (i + 1) + j * density.x + (k + 1) * density.x * density.y; triangles[offset + 35] = i + j * density.x + (k + 1) * density.x * density.y; //End the the triangle loop endTriangleLoop: continue; } } } //Create the mesh m_mesh = new Mesh(); m_mesh.indexFormat = UnityEngine.Rendering.IndexFormat.UInt32; m_mesh.vertices = pts; m_mesh.triangles = triangles; m_mesh.UploadMeshData(false); //Small multiples array m_smallMultiples = new List <VTKUnitySmallMultiple>(); m_availableUVIDs = new List <Int32>(); for (Int32 i = 0; i < 8; i++) { m_availableUVIDs.Add(i); } return(true); }
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); } } }