/// <summary> /// Constructor copy /// </summary> /// <param name="color">The color to copy</param> public LABColor(LABColor color) { L = color.L; A = color.A; B = color.B; Transparency = color.Transparency; }
/// <summary> /// Convert a CIELAB colorspace value into a MSH colorspace value /// </summary> /// <param name="color">The CIELAB color space value</param> public void FromLABColor(LABColor color) { M = (float)Math.Sqrt(color.L * color.L + color.A * color.A + color.B * color.B); S = (float)Math.Acos(color.L / M); H = (float)Math.Atan2(color.B, color.A); A = color.Transparency; }
/// <summary> /// Change the color range to apply (0.0 = minimum value, 1.0 = maximum value) /// <param name="minRange"> The minimum range to apply</param> /// <param name="maxRange"> The maximum range to apply</param> /// </summary> public void ChangeRangeColor(float minRange, float maxRange) { List <Vector4> colors = new List <Vector4>(); foreach (float v in m_values) { float c = (v - m_minVal) / (m_maxVal - m_minVal); //LAB color space (warm - cold) Color col; 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(); } if (c < minRange || c > maxRange) { col.a = 0.0f; } colors.Add(new Vector4(col.r, col.g, col.b, col.a)); } m_mesh.SetUVs(m_colorID, colors); m_mesh.UploadMeshData(false); m_minRangeAmp = minRange; m_maxRangeAmp = maxRange; }
/// <summary> /// MSH Constructor initialized from CIELAB /// </summary> /// <param name="color">the CIELAB color to convert</param> public MSHColor(LABColor color) { FromLABColor(color); }
/// <summary> /// Make a linear interpolation between two LAB Color /// </summary> /// <param name="c1">the first color (t=0)</param> /// <param name="c2">the second color (t=1)</param> /// <param name="t">the progression factor (between 0 and 1)</param> /// <returns>The interpolated color</returns> public static LABColor Lerp(LABColor c1, LABColor c2, float t) { return(c1 * (1.0f - t) + c2 * t); }
/// <summary> /// MSH Constructor initialized from CIELAB /// </summary> /// <param name="color">the CIELAB color to convert</param> public MSHColor(LABColor color) { M = S = H = A = 0; FromLABColor(color); }
/// <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); }