882 lines
28 KiB
C#
882 lines
28 KiB
C#
using System;
|
||
using System.IO;
|
||
using System.Drawing;
|
||
using System.Drawing.Imaging;
|
||
using System.Windows.Forms;
|
||
using ClassLibrary;
|
||
|
||
namespace Treko3D
|
||
{
|
||
#region RakurseArc
|
||
|
||
public class RakurseArc
|
||
{
|
||
int _mmToPixelsCoeff;
|
||
double _xa;
|
||
double _ya;
|
||
double _angle;
|
||
double _sweepAngle;
|
||
double _sweepAngleAnimation = 1; // 1 degree for preview
|
||
double _angleRad;
|
||
double _sweepAngleRad;
|
||
double _radius;
|
||
double _radius_base = 0.0; // !!! _radius_base for debug only
|
||
RectDouble _rect;
|
||
RectDouble _rectCircumf;
|
||
|
||
|
||
public int MmToPixelsCoeff
|
||
{
|
||
get { return _mmToPixelsCoeff; }
|
||
set { _mmToPixelsCoeff = value; }
|
||
}
|
||
|
||
public double Xa
|
||
{
|
||
get { return _xa; }
|
||
set { _xa = value; }
|
||
}
|
||
|
||
public double Ya
|
||
{
|
||
get { return _ya; }
|
||
set { _ya = value; }
|
||
}
|
||
|
||
public double Angle
|
||
{
|
||
get { return _angle; }
|
||
set { _angle = value; }
|
||
}
|
||
|
||
public double SweepAngle
|
||
{
|
||
get { return _sweepAngle; }
|
||
set { _sweepAngle = value; }
|
||
}
|
||
|
||
public double SweepAngleAnimation
|
||
{
|
||
get { return _sweepAngleAnimation; }
|
||
set { _sweepAngleAnimation = value; }
|
||
}
|
||
|
||
public double AngleRad
|
||
{
|
||
get { return _angleRad; }
|
||
set { _angleRad = value; }
|
||
}
|
||
|
||
public double SweepAngleRad
|
||
{
|
||
get { return _sweepAngleRad; }
|
||
set { _sweepAngleRad = value; }
|
||
}
|
||
|
||
public double Radius
|
||
{
|
||
get { return _radius; }
|
||
set { _radius = value; }
|
||
}
|
||
|
||
public RectDouble Rect
|
||
{
|
||
get { return _rect; }
|
||
set { _rect = value; }
|
||
}
|
||
|
||
//Arc circumference rectangle (smaller than Rect)
|
||
public RectDouble RectCircumf
|
||
{
|
||
get { return _rectCircumf; }
|
||
set { _rectCircumf = value; }
|
||
}
|
||
|
||
RakurseArc()
|
||
{
|
||
}
|
||
|
||
public RakurseArc(double xa, double ya, double angle, double sweepAngle, int mmToPixelsCoeff)
|
||
{
|
||
_xa = xa;
|
||
_ya = ya;
|
||
_angle = angle;// - sweepAngle/2;
|
||
_sweepAngle = sweepAngle;
|
||
_angleRad = _angle * Math.PI / 180;
|
||
_sweepAngleRad = _sweepAngle * Math.PI / 180;
|
||
_mmToPixelsCoeff = mmToPixelsCoeff;
|
||
//_radius = r;
|
||
}
|
||
|
||
public int MmToPixels(double x)
|
||
{
|
||
return Convert.ToInt32(x * _mmToPixelsCoeff);
|
||
}
|
||
|
||
|
||
public void CalcRadiusFromColors(double radiusMax, int r, int g, int b)
|
||
{
|
||
int color = (r + g + b) / 3;
|
||
_radius = _radius_base + color * radiusMax / 255; // !!! _radius_base for debug only
|
||
}
|
||
|
||
// We have radius in mm
|
||
// The width of frame 0.2 mm or 1024 pixels
|
||
// So the size of radius in pixels Rpix = _radius*1024/0.2
|
||
// This is rectangle only for draw arc
|
||
public void CalcRectangleOfArc()
|
||
{
|
||
//_rect = new Rectangle(20, 20, 20, 20);
|
||
//return;
|
||
double A = 0;
|
||
|
||
if (_radius > 0)
|
||
{
|
||
// distances to center of arc from center of arc segment
|
||
double dx = _radius * Math.Cos(_angleRad + A);
|
||
double dy = _radius * Math.Sin(_angleRad + A);
|
||
|
||
// center of arc coordinates from left upper point of hologram
|
||
double xc = _xa - dx;
|
||
double yc = _ya - dy;
|
||
|
||
// point 0 of rectangle
|
||
double x0 = xc - _radius;
|
||
double y0 = yc - _radius;
|
||
|
||
// point 1 of rectangle
|
||
double rectWidth = _radius * 2;
|
||
double rectHeight = rectWidth;
|
||
|
||
_rect = new RectDouble(x0, y0, rectWidth, rectHeight); // !!!
|
||
//_rect = new Rectangle(10, 10, 20, 20);
|
||
}
|
||
}
|
||
|
||
// Circumference rectangle to check if it intersects with frame
|
||
// to draw in it
|
||
public void CalcRectangleCircumfOfArc()
|
||
{
|
||
//_rect = new Rectangle(20, 20, 20, 20);
|
||
//return;
|
||
double A = 0;
|
||
|
||
if (_radius > 0)
|
||
{
|
||
// distances to center of arc from center of arc segment
|
||
double dx = _radius * Math.Cos(_angleRad + A);
|
||
double dy = _radius * Math.Sin(_angleRad + A);
|
||
|
||
// center of arc coordinates from left upper point of hologram
|
||
double xc = _xa - dx;
|
||
double yc = _ya - dy;
|
||
|
||
// point 0 of rectangle
|
||
|
||
//double x0 = xc + _radius * Math.Cos(_angleRad - _sweepAngleRad / 2 + A);
|
||
//double y0 = yc + _radius * Math.Sin(_angleRad - _sweepAngleRad / 2 + A);
|
||
|
||
//double x1 = xc + _radius * Math.Cos(_angleRad + _sweepAngleRad / 2 - A);
|
||
//double y1 = yc + _radius * Math.Sin(_angleRad + _sweepAngleRad / 2 - A);
|
||
|
||
double x0 = xc + _radius * Math.Cos(_angleRad + A);
|
||
double y0 = yc + _radius * Math.Sin(_angleRad + A);
|
||
|
||
double x1 = xc + _radius * Math.Cos(_angleRad - A);
|
||
double y1 = yc + _radius * Math.Sin(_angleRad - A);
|
||
|
||
double x0Rect = Math.Min(x0, x1);
|
||
double y0Rect = Math.Min(y0, y1);
|
||
|
||
double rectWidth = Math.Abs(x0 - x1);
|
||
double rectHeight = Math.Abs(y0 - y1);
|
||
|
||
_rectCircumf = new RectDouble(x0Rect, y0Rect, rectWidth, rectHeight);
|
||
}
|
||
}
|
||
|
||
public bool DrawArc(Graphics g)
|
||
{
|
||
if (_radius != 0)
|
||
{
|
||
Pen pen = new Pen(Color.White, 1);
|
||
//Rect.DrawArc(g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
||
Rect.DrawArc(g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle), Convert.ToSingle(_sweepAngle));
|
||
pen.Dispose();
|
||
//Rect.DrawGradationArc(g, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle/2), Convert.ToSingle(_sweepAngle));
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
public bool DrawAnimationArc(Graphics g, int angPreview, int parallaxAng)
|
||
{
|
||
if (_radius != 0)
|
||
{
|
||
//if (_angle - _sweepAngle > 0 && _angle != -4.5 && _angle != 4.5)
|
||
//{
|
||
// int i = 0;
|
||
//}
|
||
angPreview = -angPreview;
|
||
|
||
if (parallaxAng == 0)
|
||
{
|
||
Pen pen = new Pen(Color.White, 1);
|
||
//if (angPreview <= _angle - _sweepAngle / 2 && angPreview >= _angle + _sweepAngle / 2)
|
||
if (angPreview <= _angle && angPreview >= _angle + _sweepAngle)
|
||
//Rect.DrawArc(g, pen, _mmToPixelsCoeff, Convert.ToSingle(angPreview - _sweepAngleAnimation / 2), Convert.ToSingle(_sweepAngleAnimation));
|
||
Rect.DrawArc(g, pen, _mmToPixelsCoeff, Convert.ToSingle(angPreview), Convert.ToSingle(_sweepAngleAnimation));
|
||
pen.Dispose();
|
||
|
||
} else
|
||
{
|
||
Pen pen1 = new Pen(Color.Red, 1);
|
||
Pen pen2 = new Pen(Color.FromArgb(0, 150, 255), 1);
|
||
//if (angPreview <= _angle - _sweepAngle / 2 && angPreview >= _angle + _sweepAngle / 2)
|
||
if (angPreview <= _angle && angPreview >= _angle + _sweepAngle)
|
||
//Rect.DrawArc(g, pen1, _mmToPixelsCoeff, Convert.ToSingle(angPreview - _sweepAngleAnimation / 2), Convert.ToSingle(_sweepAngleAnimation));
|
||
Rect.DrawArc(g, pen1, _mmToPixelsCoeff, Convert.ToSingle(angPreview), Convert.ToSingle(_sweepAngleAnimation));
|
||
//if (angPreview + parallaxAng <= _angle - _sweepAngle / 2 && angPreview + parallaxAng >= _angle + _sweepAngle / 2)
|
||
if (angPreview + parallaxAng <= _angle && angPreview + parallaxAng >= _angle + _sweepAngle)
|
||
//Rect.DrawArc(g, pen2, _mmToPixelsCoeff, Convert.ToSingle(angPreview + parallaxAng - _sweepAngleAnimation / 2), Convert.ToSingle(_sweepAngleAnimation));
|
||
Rect.DrawArc(g, pen2, _mmToPixelsCoeff, Convert.ToSingle(angPreview + parallaxAng), Convert.ToSingle(_sweepAngleAnimation));
|
||
pen1.Dispose();
|
||
pen2.Dispose();
|
||
}
|
||
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
public bool DrawArcFromZeroCoord(Graphics g, Pen pen)
|
||
{
|
||
if (_radius != 0)
|
||
{
|
||
//Rect.DrawArcFromZeroCoord(g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
||
Rect.DrawArcFromZeroCoord(g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle), Convert.ToSingle(_sweepAngle));
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
public bool DrawArcInFrame(RectDouble rect, Graphics g, int mmToPixelsCoeff, int[] profileColor)
|
||
{
|
||
if (_radius != 0)
|
||
{
|
||
//Rect.DrawArcInFrame(rect, _rectCircumf, g, pen, _mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle));
|
||
//Rect.DrawGradationArcInFrame(rect, _rectCircumf, g, mmToPixelsCoeff, Convert.ToSingle(_angle - _sweepAngle / 2), Convert.ToSingle(_sweepAngle), profileColor);
|
||
Rect.DrawGradationArcInFrame(rect, _rectCircumf, g, mmToPixelsCoeff, Convert.ToSingle(_angle), Convert.ToSingle(_sweepAngle), profileColor);
|
||
return true;
|
||
}
|
||
else
|
||
return false;
|
||
}
|
||
|
||
private void ClearRakurseArcBuffer()
|
||
{
|
||
//Array.Clear(_rakurseArc, 0, _rakurseArc.Length);
|
||
}
|
||
|
||
private int recalcRange(int val, int _grayHigh, int _grayLow)
|
||
{
|
||
int delta = _grayHigh - _grayLow;
|
||
int newRangeValue = _grayLow + (val * delta / 256);
|
||
return newRangeValue;
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Voxel
|
||
|
||
public class Voxel : IDisposable
|
||
{
|
||
#region Local
|
||
|
||
bool _empty = false;
|
||
int _mmToPixelsCoeff;
|
||
double _xc;
|
||
double _yc;
|
||
double _width;
|
||
double _height;
|
||
int _nRakurses;
|
||
double _radiusMax;
|
||
RectDouble _rectMax;
|
||
private RakurseArc[] _rakurseArcs;
|
||
|
||
#endregion
|
||
|
||
#region Get/Set
|
||
|
||
public bool Empty
|
||
{
|
||
get { return _empty; }
|
||
set { _empty = value; }
|
||
}
|
||
|
||
public int MmToPixelsCoeff
|
||
{
|
||
get { return _mmToPixelsCoeff; }
|
||
set { _mmToPixelsCoeff = value; }
|
||
}
|
||
|
||
public double Xc
|
||
{
|
||
get { return _xc; }
|
||
}
|
||
|
||
public double Yc
|
||
{
|
||
get { return _yc; }
|
||
}
|
||
|
||
public double Width
|
||
{
|
||
get { return _width; }
|
||
}
|
||
|
||
public double Height
|
||
{
|
||
get { return _height; }
|
||
}
|
||
|
||
public int NRakurses
|
||
{
|
||
get { return _nRakurses; }
|
||
}
|
||
|
||
public RakurseArc[] RakurseArcs
|
||
{
|
||
get { return _rakurseArcs; }
|
||
}
|
||
|
||
public double RadiusMax
|
||
{
|
||
get { return _radiusMax; }
|
||
set { _radiusMax = value; }
|
||
}
|
||
|
||
public RectDouble RectMax
|
||
{
|
||
get { return _rectMax; }
|
||
set { _rectMax = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
Voxel()
|
||
{
|
||
}
|
||
|
||
public Voxel(double xc, double yc, int nRakurses, double radiusMax, int mmToPixelsCoeff)
|
||
{
|
||
_xc = xc;
|
||
_yc = yc;
|
||
_nRakurses = nRakurses;
|
||
_radiusMax = radiusMax;
|
||
_mmToPixelsCoeff = mmToPixelsCoeff;
|
||
|
||
//int ArcHeight=0;
|
||
//int ArcWidth=0;
|
||
|
||
_rakurseArcs = new RakurseArc[nRakurses];
|
||
|
||
int sweepAngle = -180 / nRakurses; //contrclockwhise
|
||
int curAngle = 0;
|
||
|
||
for (int nArc = 0; nArc < _rakurseArcs.Length; nArc++)
|
||
{
|
||
_rakurseArcs[nArc] = new RakurseArc(_xc, _yc, curAngle, sweepAngle, mmToPixelsCoeff);
|
||
curAngle += sweepAngle;
|
||
}
|
||
}
|
||
|
||
public bool DrawArcs(Image imgTreko3D)
|
||
{
|
||
Pen whitePen = new Pen(Color.White, 1);
|
||
Graphics g = Graphics.FromImage(imgTreko3D); //.CreateGraphics();
|
||
|
||
using (g)
|
||
foreach (RakurseArc rArc in _rakurseArcs)
|
||
{
|
||
rArc.MmToPixelsCoeff = _mmToPixelsCoeff;
|
||
rArc.DrawArc(g);
|
||
//if (rArc.DrawArc(g) == true)
|
||
// _empty = false;
|
||
//else
|
||
// _empty = true;
|
||
}
|
||
|
||
whitePen.Dispose();
|
||
g.Dispose();
|
||
|
||
return _empty;
|
||
//pbVoxel.Scale()
|
||
}
|
||
|
||
public bool DrawAnimationArcs(Image imgTreko3D, int angPreview, int parallaxAng)
|
||
{
|
||
Pen whitePen = new Pen(Color.White, 1);
|
||
Graphics g = Graphics.FromImage(imgTreko3D); //.CreateGraphics();
|
||
|
||
using (g)
|
||
foreach (RakurseArc rArc in _rakurseArcs)
|
||
{
|
||
rArc.MmToPixelsCoeff = _mmToPixelsCoeff;
|
||
rArc.DrawAnimationArc(g, angPreview, parallaxAng);
|
||
//if (rArc.DrawAnimationArc(g, angPreview) == true)
|
||
// _empty = false;
|
||
//else
|
||
// _empty = true;
|
||
}
|
||
|
||
whitePen.Dispose();
|
||
g.Dispose();
|
||
|
||
return _empty;
|
||
//pbVoxel.Scale()
|
||
}
|
||
|
||
public void DrawArcs(Bitmap bmp)
|
||
{
|
||
Pen whitePen = new Pen(Color.White, 2);
|
||
Graphics g = Graphics.FromImage(bmp); //.CreateGraphics();
|
||
|
||
using (g)
|
||
foreach (RakurseArc rArc in _rakurseArcs)
|
||
rArc.DrawArcFromZeroCoord(g, whitePen);
|
||
|
||
whitePen.Dispose();
|
||
g.Dispose();
|
||
//pbVoxel.Scale()
|
||
}
|
||
|
||
public void CalcСircumfRectangle()
|
||
{
|
||
RectDouble rect;
|
||
double xMin = double.MaxValue;
|
||
double yMin = double.MaxValue;
|
||
double xMax = double.MinValue;
|
||
double yMax = double.MinValue;
|
||
foreach (RakurseArc rArc in _rakurseArcs)
|
||
{
|
||
if (rArc.Radius == 0) // The pixel in source rakurse file is black
|
||
continue;
|
||
rect = rArc.Rect;
|
||
if (xMin > rect.X) { xMin = rect.X; }
|
||
if (yMin > rect.Y) { yMin = rect.Y; }
|
||
if (xMax < rect.X + rect.Width) { xMax = rect.X + rect.Width; }
|
||
if (yMax < rect.Y + rect.Height) { yMax = rect.Y + rect.Height; }
|
||
}
|
||
|
||
RectMax = new RectDouble(xMin, yMin, xMax - xMin, yMax - yMin);
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
RectMax = null;
|
||
|
||
//for (int i = 0; i < _rakurseArcs.Length; i++)
|
||
//{
|
||
// _rakurseArcs[i].Rect = null;
|
||
// _rakurseArcs[i].RectCircumf = null;
|
||
// _rakurseArcs[i] = null;
|
||
//}
|
||
//_rakurseArcs = null;
|
||
}
|
||
|
||
}
|
||
|
||
#endregion
|
||
|
||
#region Strip
|
||
|
||
public class Strip : IDisposable
|
||
{
|
||
|
||
#region Private
|
||
|
||
private bool _empty = false;
|
||
private Treko3D _treko3DObj;
|
||
private int _mmToPixelsCoeff;
|
||
private string[] _rakurseFiles;
|
||
private Bitmap[] _rakurseBmps;
|
||
private int _nRakurses;
|
||
private int _imageWidth;
|
||
private int _imageHeight;
|
||
private double _radiusMax;
|
||
private Bitmap _stripBmp;
|
||
private Voxel[] _voxelArray;
|
||
private int _stripWidth;
|
||
private int _stripHeight;
|
||
private double _voxelStep;
|
||
private int _nStrip;
|
||
private string _prefix;
|
||
|
||
#endregion
|
||
|
||
#region Get/Set
|
||
|
||
public bool Empty
|
||
{
|
||
get { return _empty; }
|
||
set { _empty = value; }
|
||
}
|
||
|
||
public Treko3D Treko3Dobj
|
||
{
|
||
get { return _treko3DObj; }
|
||
set { _treko3DObj = value; }
|
||
}
|
||
|
||
public int MmToPixelsCoeff
|
||
{
|
||
get { return _mmToPixelsCoeff; }
|
||
set { _mmToPixelsCoeff = value; }
|
||
}
|
||
|
||
public string[] RakurseFiles
|
||
{
|
||
get { return _rakurseFiles; }
|
||
set { _rakurseFiles = value; }
|
||
}
|
||
public Bitmap[] RakurseBmps
|
||
{
|
||
get { return _rakurseBmps; }
|
||
set { _rakurseBmps = value; }
|
||
}
|
||
public int ImageWidth
|
||
{
|
||
get { return _imageWidth; }
|
||
set { _imageWidth = value; }
|
||
}
|
||
public int ImageHeight
|
||
{
|
||
get { return _imageHeight; }
|
||
set { _imageHeight = value; }
|
||
}
|
||
public double RadiusMax
|
||
{
|
||
get { return _radiusMax; }
|
||
set { _radiusMax = value; }
|
||
}
|
||
public int NRakurses
|
||
{
|
||
get { return _nRakurses; }
|
||
set { _nRakurses = value; }
|
||
}
|
||
public Bitmap StripBmp
|
||
{
|
||
get { return _stripBmp; }
|
||
set { _stripBmp = value; }
|
||
}
|
||
public Voxel[] VoxelArray
|
||
{
|
||
get { return _voxelArray; }
|
||
set { _voxelArray = value; }
|
||
}
|
||
public double VoxelStep
|
||
{
|
||
get { return _voxelStep; }
|
||
set { _voxelStep = value; }
|
||
}
|
||
public int StripWidth
|
||
{
|
||
get { return _stripWidth; }
|
||
set { _stripWidth = value; }
|
||
}
|
||
public int StripHeight
|
||
{
|
||
get { return _stripHeight; }
|
||
set { _stripHeight = value; }
|
||
}
|
||
public int NStrip
|
||
{
|
||
get { return _nStrip; }
|
||
set { _nStrip = value; }
|
||
}
|
||
|
||
#endregion
|
||
|
||
Strip()
|
||
{
|
||
|
||
}
|
||
|
||
public Strip(int nStrip, Treko3D treko3DObj) //string[] rakurseFiles)
|
||
{
|
||
_empty = false;
|
||
_nStrip = nStrip;
|
||
_treko3DObj = treko3DObj;
|
||
_rakurseFiles = treko3DObj.RakurseFiles;
|
||
_nRakurses = _rakurseFiles.Length;
|
||
_radiusMax = treko3DObj.RadiusMax;
|
||
//_mmToPixelsCoeff = treko3DObj.MmToPixelsCoeff;
|
||
_voxelStep = treko3DObj.Step;
|
||
_rakurseBmps = treko3DObj.RakurseBmps;
|
||
_imageWidth = _rakurseBmps[0].Width;
|
||
_imageHeight = _rakurseBmps[0].Height;
|
||
_treko3DObj.ImageWidthPix = _imageWidth;
|
||
_treko3DObj.ImageHeightPix = _imageHeight;
|
||
|
||
_voxelArray = new Voxel[_imageWidth]; // (_stripWidth, _stripHeight, _nRakurses, _color)[_imageWidth];
|
||
|
||
double xc = 0;
|
||
double yc = _voxelStep * nStrip;
|
||
for (int nCol = 0; nCol < _voxelArray.Length; nCol++)
|
||
{
|
||
_voxelArray[nCol] = new Voxel(xc, yc, _nRakurses, _radiusMax, _mmToPixelsCoeff);
|
||
xc += _voxelStep;
|
||
}
|
||
|
||
}
|
||
|
||
public void CalcVoxelsСircumfRectangle()
|
||
{
|
||
foreach (Voxel voxel in _voxelArray)
|
||
if (voxel.Empty == false)
|
||
voxel.CalcСircumfRectangle();
|
||
}
|
||
|
||
public int MmToPixels(double x)
|
||
{
|
||
return Convert.ToInt32(x * _mmToPixelsCoeff);
|
||
}
|
||
|
||
public void AddRakurseFileToStrip(Bitmap sourceBmp, int nRakurse, int nRow, int decimate)
|
||
{
|
||
BitmapData sourceData = null;
|
||
|
||
// Init
|
||
sourceData = sourceBmp.LockBits(new Rectangle(0, nRow, _imageWidth, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||
|
||
// Process
|
||
Size sizeSource = sourceBmp.Size;
|
||
unsafe
|
||
{
|
||
byte* sourceScanlineBytes = (byte*)sourceData.Scan0;
|
||
int* sourceScanline = (int*)sourceScanlineBytes;
|
||
int i = 0;
|
||
for (int nPixel = 0; nPixel < sizeSource.Width; nPixel += decimate)
|
||
{
|
||
int color = sourceScanline[nPixel];
|
||
if (color != -16777216)
|
||
i = 1;
|
||
|
||
FillStripRakurseArcArray(color, nRakurse, nPixel, nRow);
|
||
}
|
||
}
|
||
|
||
// Finalize
|
||
if (sourceData != null)
|
||
sourceBmp.UnlockBits(sourceData);
|
||
|
||
//if (destData != null)
|
||
// StripBmp.UnlockBits(destData);
|
||
}
|
||
|
||
public void AddRakurseFileToStrip(Bitmap sourceBmp, int nRakurse, int nRow, int nVoxelStart, int nVoxelEnd)
|
||
{
|
||
BitmapData sourceData = null;
|
||
|
||
// Init
|
||
sourceData = sourceBmp.LockBits(new Rectangle(0, nRow, _imageWidth, 1), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
|
||
|
||
// Process
|
||
Size sizeSource = sourceBmp.Size;
|
||
unsafe
|
||
{
|
||
byte* sourceScanlineBytes = (byte*)sourceData.Scan0;
|
||
int* sourceScanline = (int*)sourceScanlineBytes;
|
||
int i = 0;
|
||
for (int nPixel = nVoxelStart; nPixel < nVoxelEnd; nPixel++)
|
||
{
|
||
int color = sourceScanline[nPixel];
|
||
if (color != -16777216)
|
||
i = 1;
|
||
|
||
FillStripRakurseArcArray(color, nRakurse, nPixel, nRow);
|
||
}
|
||
}
|
||
|
||
// Finalize
|
||
if (sourceData != null)
|
||
sourceBmp.UnlockBits(sourceData);
|
||
|
||
//if (destData != null)
|
||
// StripBmp.UnlockBits(destData);
|
||
|
||
}
|
||
|
||
|
||
public string GetUntilOrEmpty(string text, string stopAt = "_")
|
||
{
|
||
if (!String.IsNullOrWhiteSpace(text))
|
||
{
|
||
int charLocation = text.IndexOf(stopAt, StringComparison.Ordinal);
|
||
|
||
if (charLocation > 0)
|
||
{
|
||
return text.Substring(0, charLocation);
|
||
}
|
||
}
|
||
|
||
return String.Empty;
|
||
}
|
||
|
||
private FileInfo getFileName(int nRow, string path)
|
||
{
|
||
string dir = Path.GetDirectoryName(path);
|
||
string fileName = Path.GetFileNameWithoutExtension(path);
|
||
_prefix = GetUntilOrEmpty(fileName, "_");
|
||
_prefix = "nika";
|
||
string fileExt = ".png"; // Path.GetExtension(path);
|
||
|
||
path = Path.Combine(dir, _prefix + "_" + nRow + fileExt);
|
||
return new FileInfo(path);
|
||
}
|
||
|
||
|
||
public void GenerateAndSaveStrips(string path, int decimate)
|
||
{
|
||
for (int nRow = 0; nRow < ImageHeight; nRow += decimate)
|
||
{
|
||
FileInfo stripFile = getFileName(nRow, path);
|
||
GenerateAndSaveStrip(nRow, stripFile.FullName, decimate);
|
||
}
|
||
}
|
||
|
||
public void GenerateAndSaveStrip(int nStrip, string fileName, int decimate)
|
||
{
|
||
|
||
ConstructStripUsingRakurses(nStrip, decimate);
|
||
//ConvertToTwoDimensionalBitArray(_stripWidth, _stripHeight, _nRakurses);
|
||
|
||
//// For test only
|
||
//FileInfo txtFileInfo = getTextFileName(fileName);
|
||
//FileInfo bmpFileInfo = getBmpFileName(fileName);
|
||
//Voxel voxel = _voxelArray[0];
|
||
//RakurseColumn rakurseCol = voxel.RakurseColumns[0];
|
||
//print2DimBitArrayToTextFile(rakurseCol.RakurseColumnBuffer, rakurseCol.Width, rakurseCol.Height, txtFileInfo.FullName);
|
||
//print2DimBitArrayToTextFile(_twoDimensionalResultArray, rakurseCol.Width*4, rakurseCol.Height, txtFileInfo.FullName);
|
||
//print2DimBitArrayToPicture(rakurseCol.RakurseColumnBuffer, rakurseCol.Width, rakurseCol.Height, pngFileInfo.FullName);
|
||
|
||
//int stripWidth = _twoDimensionalResultArray.GetLength(0);
|
||
//int stripHeight = _twoDimensionalResultArray.GetLength(1);
|
||
//print2DimBitArrayToPicture(_twoDimensionalResultArray, stripWidth, stripHeight, fileName);
|
||
|
||
}
|
||
|
||
public void GenerateStrip(int nStrip, int nVoxelStart, int nVoxelEnd)
|
||
{
|
||
ConstructStripUsingRakurses(nStrip, nVoxelStart, nVoxelEnd);
|
||
}
|
||
|
||
public void ConstructStripUsingRakurses(int nStrip, int decimate)
|
||
{
|
||
for (int i = 0; i < NRakurses; i++)
|
||
{
|
||
try
|
||
{
|
||
AddRakurseFileToStrip(RakurseBmps[i], i, nStrip, decimate);
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
MessageBox.Show(exception.Message, exception.GetType().FullName);
|
||
}
|
||
}
|
||
}
|
||
|
||
public void ConstructStripUsingRakurses(int nStrip, int nVoxelStart, int nVoxelEnd)
|
||
{
|
||
for (int i = 0; i < NRakurses; i++)
|
||
{
|
||
try
|
||
{
|
||
AddRakurseFileToStrip(RakurseBmps[i], i, nStrip, nVoxelStart, nVoxelEnd);
|
||
}
|
||
catch (Exception exception)
|
||
{
|
||
MessageBox.Show(exception.Message, exception.GetType().FullName);
|
||
}
|
||
}
|
||
}
|
||
|
||
// 1. Take Voxel from array of voxels by nCol index.
|
||
// 2. In that Voxel take RakurseArc from array of rackurseArcs by nRakurse index.
|
||
// 3. In that RakurseArc calculate radius=RadiusMax*Color/255.
|
||
private void FillStripRakurseArcArray(int color, int nRakurse, int nCol, int nRow)
|
||
{
|
||
int r = (color >> 16) & 0xFF;
|
||
int g = (color >> 8) & 0xFF;
|
||
int b = color & 0xFF;
|
||
|
||
Voxel voxel = _voxelArray[nCol];
|
||
RakurseArc rakurseArc = voxel.RakurseArcs[nRakurse];
|
||
rakurseArc.CalcRadiusFromColors(_radiusMax, r, g, b);
|
||
rakurseArc.CalcRectangleOfArc();
|
||
rakurseArc.CalcRectangleCircumfOfArc();
|
||
|
||
// values r,g,b of each source pixel we need for statistics procedures
|
||
//voxel.R = r;
|
||
//voxel.G = g;
|
||
//voxel.B = b;
|
||
}
|
||
|
||
public void DrawOnPictureBox(Image imgTreko3D, int mmToPixelsCoeff)
|
||
{
|
||
//_empty = true;
|
||
_mmToPixelsCoeff = mmToPixelsCoeff;
|
||
foreach (Voxel voxel in _voxelArray)
|
||
{
|
||
if (voxel.Empty == false)
|
||
{
|
||
voxel.MmToPixelsCoeff = _mmToPixelsCoeff;
|
||
voxel.DrawArcs(imgTreko3D);
|
||
voxel.Empty = voxel.DrawArcs(imgTreko3D);
|
||
//if (voxel.Empty == false)
|
||
// _empty = false;
|
||
}
|
||
}
|
||
}
|
||
|
||
public void DrawAnimation(Image imgTreko3D, int angPreview, int parallaxAng, int mmToPixelsCoeff)
|
||
{
|
||
_empty = true;
|
||
_mmToPixelsCoeff = mmToPixelsCoeff;
|
||
foreach (Voxel voxel in _voxelArray)
|
||
{
|
||
//if (voxel.Empty == false)
|
||
//{
|
||
voxel.MmToPixelsCoeff = _mmToPixelsCoeff;
|
||
voxel.Empty = voxel.DrawAnimationArcs(imgTreko3D, angPreview, parallaxAng);
|
||
//if (voxel.Empty == false)
|
||
// _empty = false;
|
||
//}
|
||
}
|
||
}
|
||
|
||
public void Dispose()
|
||
{
|
||
|
||
for (int i = 0; i < _voxelArray.Length; i++)
|
||
{
|
||
_voxelArray[i].Dispose();
|
||
_voxelArray[i] = null;
|
||
}
|
||
|
||
_voxelArray = null;
|
||
|
||
if (_stripBmp != null)
|
||
_stripBmp.Dispose();
|
||
}
|
||
}
|
||
#endregion
|
||
|
||
}
|