/// <summary> /// Creates a transfer function from RGB and alpha cubic splines. /// </summary> /// <param name="tcp">Transfer control points to use.</param> /// <returns>An array of RGBA colors corresponding to each isovalue 0-255.</returns> public static Color[] CreateTransferFunction(TransferControlPoints tcp) { Debug.Assert(tcp.rgbPoints.Count == tcp.rgbIsoValues.Count); Debug.Assert(tcp.alphaPoints.Count == tcp.alphaIsoValues.Count); Debug.Assert(tcp.rgbIsoValues[0] == 0 && tcp.rgbIsoValues[tcp.rgbIsoValues.Count - 1] == 255, "The first and last isovalues must be 0 and 255, respectively."); Debug.Assert(tcp.alphaIsoValues[0] == 0 && tcp.alphaIsoValues[tcp.alphaIsoValues.Count - 1] == 255, "The first and last isovalues must be 0 and 255, respectively."); // Calculate the cubic splines for the RGB and alpha values. CubicSpline <Cubic3> rgbSpline = new CubicSpline <Cubic3>(); CubicSpline <Cubic1> alphaSpline = new CubicSpline <Cubic1>(); rgbSpline.Calculate(tcp.rgbPoints); alphaSpline.Calculate(tcp.alphaPoints); // Create the transfer function from the two splines. Color[] transferFunc = new Color[256]; // ...RGB portion. int index = 0; for (int i = 0; i < rgbSpline.Count; ++i) { int interval = tcp.rgbIsoValues[i + 1] - tcp.rgbIsoValues[i]; Debug.Assert(interval > 0, "Isovalues must be incremental by at least 1/increment."); // Fill in the color at the isovalues covered by the current spline segment. for (int j = 0; j < interval; ++j) { float position = j / (float)interval; transferFunc[index++] = rgbSpline.GetPointOnSpline(i, position).ToColor(); } } transferFunc[index] = rgbSpline.GetPointOnSpline(rgbSpline.Count - 1, 1f).ToColor(); // ...alpha portion. index = 0; for (int i = 0; i < alphaSpline.Count; ++i) { int interval = tcp.alphaIsoValues[i + 1] - tcp.alphaIsoValues[i]; Debug.Assert(interval > 0, "Isovalues must be incremental by at least 1/increment."); // Fill in the alpha at the isovalues covered by the current spline segment. for (int j = 0; j < interval; ++j) { float position = j / (float)interval; transferFunc[index++].A = alphaSpline.GetPointOnSpline(i, position).ToByte(); } } transferFunc[index].A = alphaSpline.GetPointOnSpline(alphaSpline.Count - 1, 1f).ToByte(); return(transferFunc); }
/// <summary> /// Creates a transfer function from RGB and alpha cubic splines. /// </summary> /// <param name="tcp">Transfer control points to use.</param> /// <returns>An array of RGBA colors corresponding to each isovalue 0-255.</returns> public static Color[] CreateTransferFunction(TransferControlPoints tcp) { Debug.Assert(tcp.rgbPoints.Count == tcp.rgbIsoValues.Count); Debug.Assert(tcp.alphaPoints.Count == tcp.alphaIsoValues.Count); Debug.Assert(tcp.rgbIsoValues[0] == 0 && tcp.rgbIsoValues[tcp.rgbIsoValues.Count - 1] == 255, "The first and last isovalues must be 0 and 255, respectively."); Debug.Assert(tcp.alphaIsoValues[0] == 0 && tcp.alphaIsoValues[tcp.alphaIsoValues.Count - 1] == 255, "The first and last isovalues must be 0 and 255, respectively."); // Calculate the cubic splines for the RGB and alpha values. CubicSpline<Cubic3> rgbSpline = new CubicSpline<Cubic3>(); CubicSpline<Cubic1> alphaSpline = new CubicSpline<Cubic1>(); rgbSpline.Calculate(tcp.rgbPoints); alphaSpline.Calculate(tcp.alphaPoints); // Create the transfer function from the two splines. Color[] transferFunc = new Color[256]; // ...RGB portion. int index = 0; for (int i = 0; i < rgbSpline.Count; ++i) { int interval = tcp.rgbIsoValues[i + 1] - tcp.rgbIsoValues[i]; Debug.Assert(interval > 0, "Isovalues must be incremental by at least 1/increment."); // Fill in the color at the isovalues covered by the current spline segment. for (int j = 0; j < interval; ++j) { float position = j / (float)interval; transferFunc[index++] = rgbSpline.GetPointOnSpline(i, position).ToColor(); } } transferFunc[index] = rgbSpline.GetPointOnSpline(rgbSpline.Count - 1, 1f).ToColor(); // ...alpha portion. index = 0; for (int i = 0; i < alphaSpline.Count; ++i) { int interval = tcp.alphaIsoValues[i + 1] - tcp.alphaIsoValues[i]; Debug.Assert(interval > 0, "Isovalues must be incremental by at least 1/increment."); // Fill in the alpha at the isovalues covered by the current spline segment. for (int j = 0; j < interval; ++j) { float position = j / (float)interval; transferFunc[index++].A = alphaSpline.GetPointOnSpline(i, position).ToByte(); } } transferFunc[index].A = alphaSpline.GetPointOnSpline(alphaSpline.Count - 1, 1f).ToByte(); return transferFunc; }