BigLitho/Large.Lito.Database/Make3_Treko3D/Frames/Frames.cs

837 lines
26 KiB
C#

using System;
using System.Drawing;
using System.Drawing.Imaging;
using System.Collections.Generic;
using Treko;
using Treko3D;
using ClassLibrary;
namespace Frames
{
#region Frame
public class Frame
{
double _x0;
double _y0;
double _width;
double _height;
int _fW = 1024;
int _fH = 768;
int _nFile; // Number of File
bool _isBlack; // Bitmap marked as black, not for save to file
bool _shifted; // Frames in odd rows should be shifted to the left in half frame
#region properties
public double X0
{
get { return _x0; }
set { _x0 = value; }
}
public double Y0
{
get { return _y0; }
set { _y0 = value; }
}
public double Width
{
get { return _width; }
set { _width = value; }
}
public double Height
{
get { return _height; }
set { _height = value; }
}
public int FrmResW
{
get { return _fW; }
set { _fW = value; }
}
public int FrmResH
{
get { return _fH; }
set { _fH = value; }
}
public int NFile
{
get { return _nFile; }
set { _nFile = value; }
}
public bool IsBlack
{
get { return _isBlack; }
set { _isBlack = value; }
}
public bool Shifted
{
get { return _shifted; }
set { _shifted = value; }
}
public Frame(int ResW, int ResH, double sizeW, double sizeH)
{
_fW = ResW;
_fH = ResH;
_width = sizeW;
_height = sizeH;
_isBlack = false;
_shifted = false;
}
#endregion
public Rectangle FrameRect(int i, int j)
{
int x0 = i * FrmResW;
int y0 = j * FrmResH;
if (_shifted == true) // shift to make bricks
x0 += FrmResW / 2;
return new Rectangle(x0, y0, FrmResW, FrmResH);
}
}
#endregion
#region FrameGroup
public class FrameGroup: IDisposable
{
#region Private
double _x0;
double _y0;
int _mmToPixelsCoeff;
Bitmap _frameGroupBmp;
bool _isBlack;
List<RakurseArc> _rakurseArcs = new List<RakurseArc>();
List<ColorArc> _colorArcs = new List<ColorArc>();
double _frameWidth;
double _frameHeight;
int _frameWidthPix = 1024;
int _frameHeightPix = 768;
int _nFramesHor;
int _nFramesVert;
int _nGroupHor;
int _nGroupVert;
RectDouble _rect;
Frame[,] _frameMap;
Bitmap[,] _bmpMap;
int _voxelRowRangeStart = 0;
int _voxelRowRangeEnd = 0;
int _voxelColRangeStart = 0;
int _voxelColRangeEnd = 0;
int _colorPixelRowRangeStart = 0;
int _colorPixelRowRangeEnd = 0;
int _colorPixelColRangeStart = 0;
int _colorPixelColRangeEnd = 0;
#endregion
#region Get/Set
public double X0
{
get { return _x0; }
set { _x0 = value; }
}
public double Y0
{
get { return _y0; }
set { _y0 = value; }
}
// Width of frame in mm
public double FrameWidth
{
get { return _frameWidth; }
set { _frameWidth = value; }
}
// Height of frame in mm
public double FrameHeight
{
get { return _frameHeight; }
set { _frameHeight = value; }
}
public int FrmWidthPix
{
get { return _frameWidthPix; }
set { _frameWidthPix = value; }
}
public int FrmHeightPix
{
get { return _frameHeightPix; }
set { _frameHeightPix = value; }
}
// To make bricks: extend width of frame group in half of frame
public int GrpWidthPix
{
//get { return _frameWidthPix * NFramesHor + _frameWidthPix / 2; }
get { return _frameWidthPix * NFramesHor; }
}
public int GrpHeightPix
{
get { return _frameHeightPix * NFramesVert; }
}
// To make bricks: extend width of frame group in half of frame
public double GrpWidth
{
//get { return _frameWidth * NFramesHor + _frameWidth / 2; }
get { return _frameWidth * NFramesHor; }
}
public double GrpHeight
{
get { return _frameHeight * NFramesVert; }
}
// Number of frames in Group horizontally
public int NFramesHor
{
get { return _nFramesHor; }
}
// Number of frames in Group vertically
public int NFramesVert
{
get { return _nFramesVert; }
}
// Group's number horizontally
public int NGroupHor
{
get { return _nGroupHor; }
}
// Group's number vertically
public int NGroupVert
{
get { return _nGroupVert; }
}
public Bitmap FrameGroupBmp
{
get { return _frameGroupBmp; }
set { _frameGroupBmp = value; }
}
public Frame[,] FrameMap
{
get { return _frameMap; }
set { _frameMap = value; }
}
public Bitmap[,] BmpMap
{
get { return _bmpMap; }
set { _bmpMap = value; }
}
public RectDouble Rect
{
get { return _rect; }
}
public List<RakurseArc> IntersectRakurseArcs
{
get { return _rakurseArcs; }
set { _rakurseArcs = value; }
}
public List<ColorArc> IntersectColorArcs
{
get { return _colorArcs; }
set { _colorArcs = value; }
}
public int MmToPixelsCoeff
{
get
{
//// GrpWidthPix is extended in half frame for bricks construction
//if (_mmToPixelsCoeff == 0)
// _mmToPixelsCoeff = Convert.ToInt32(GrpWidthPix / (_frameWidth + _frameWidth/2));
if (_mmToPixelsCoeff == 0)
_mmToPixelsCoeff = Convert.ToInt32(GrpWidthPix / GrpWidth);
return _mmToPixelsCoeff;
}
set { _mmToPixelsCoeff = value; }
}
public bool IsBlack
{
get { return _isBlack; }
set { _isBlack = value; }
}
public int VoxelRowRangeStart
{
get { return _voxelRowRangeStart; }
set { _voxelRowRangeStart = value; }
}
public int VoxelRowRangeEnd
{
get { return _voxelRowRangeEnd; }
set { _voxelRowRangeEnd = value; }
}
public int VoxelColRangeStart
{
get { return _voxelColRangeStart; }
set { _voxelColRangeStart = value; }
}
public int VoxelColRangeEnd
{
get { return _voxelColRangeEnd; }
set { _voxelColRangeEnd = value; }
}
public int ColorPixelRowRangeStart
{
get { return _colorPixelRowRangeStart; }
set { _colorPixelRowRangeStart = value; }
}
public int ColorPixelRowRangeEnd
{
get { return _colorPixelRowRangeEnd; }
set { _colorPixelRowRangeEnd = value; }
}
public int ColorPixelColRangeStart
{
get { return _colorPixelColRangeStart; }
set { _colorPixelColRangeStart = value; }
}
public int ColorPixelColRangeEnd
{
get { return _colorPixelColRangeEnd; }
set { _colorPixelColRangeEnd = value; }
}
#endregion
string genFileName(int nFile)
{
//int fileNumber = _nGroupVert * _nFramesHor + _nGroupHor + 1; // Start from 1 not 0
string fName = nFile.ToString();
fName = fName.PadLeft(6, '0');
return fName;
}
public void CropIntoImageArray()
{
FastImageCroper fIC = new FastImageCroper(_frameGroupBmp);
BmpMap = new Bitmap[_nFramesHor, _nFramesVert];
for (int j = 0; j < _nFramesVert; j++)
{
for (int i = 0; i < _nFramesHor; i++)
{
Frame fr = FrameMap[i, j];
Rectangle rect = fr.FrameRect(i, j);
Bitmap bmp = fIC.Crop(rect);
BmpMap[i, j] = bmp;
}
}
fIC.Dispose();
}
// we need to crop group of frames as bricks with shift in half of frame for odd rows
public void CropIntoImageArray(int nGroupRow)
{
//bool nFramesIsEven = (_nFramesVert % 2 == 0); // Number of frames in Row is even (chetnyj)
//bool nGroupRowIsEven = (nGroupRow % 2 == 0); // Number of GroupRow is even (chetnyj)
// Init Shifted value
for (int j = 0; j < _nFramesVert; j++)
for (int i = 0; i < _nFramesHor; i++)
FrameMap[i, j].Shifted = false;
//// Calculate which rows in frame group should be shifted
//if (nFramesIsEven == true || nGroupRowIsEven == true) // V gruppe chetnoe kolichestvo strok, v etom sluchae sdvigaem v gruppe vlevo kajduju nechetnuju stroku
//{
// for (int j = 1; j < _nFramesVert; j += 2)
// for (int i = 0; i < _nFramesHor; i++)
// FrameMap[i, j].Shifted = true;
//}
//else // V gruppe nechetnoe kolichestvo strok, v etom sluchae sdvigaem v gruppe vlevo kajduju nechetnuju stroku dlja chetnyh grupp
// // i kajduju chetnuju stroku dlja nechetnyh grupp
//{
//for (int j = 0; j < _nFramesVert; j += 2)
// for (int i = 0; i < _nFramesHor; i++)
// FrameMap[i, j].Shifted = true;
//}
// shift to the right every even row / because all framegroups shifted initially to the left
for (int j = 0; j < _nFramesVert; j += 2)
for (int i = 0; i < _nFramesHor; i++)
FrameMap[i, j].Shifted = true;
FastImageCroper fIC = new FastImageCroper(_frameGroupBmp);
BmpMap = new Bitmap[_nFramesHor, _nFramesVert];
for (int j = 0; j < _nFramesVert; j++)
for (int i = 0; i < _nFramesHor; i++)
{
Frame fr = FrameMap[i, j];
Rectangle rect = fr.FrameRect(i, j);
Bitmap bmp = fIC.Crop(rect);
BmpMap[i, j] = bmp;
}
fIC.Dispose();
}
private int calcNFile(int nGroupsHor, int nGroupsVert, int i, int j, int lenGroupHor, int lenGroupVert)
{
int lenFramesHor = lenGroupHor * NFramesHor; // Length of line in frames
int nFrameVert = nGroupsVert * NFramesVert + j; // Current number of frame's line
int nFrameHor = nGroupsHor * NFramesHor + i; // Current number of frame in line
int nFrame = lenFramesHor * nFrameVert + nFrameHor + 1; // Current number of frame (file), start file name == 1, not 0 !!!!
return nFrame;
}
public void SaveGroupToFiles(string outDirName, int nGroupHor, int nGroupVert, int lenGroupHor, int lenGroupVert)
{
for (int j = 0; j < _nFramesVert; j++)
{
for (int i = 0; i < _nFramesHor; i++)
{
int nFile = calcNFile(nGroupHor, nGroupVert, i, j, lenGroupHor, lenGroupVert);
FrameMap[i, j].NFile = nFile;
// nFile nachatx s 1 !!!!
string fName = genFileName(nFile);
string fPath = outDirName + "\\" + fName + ".png";
if (ImageProcessing.DetectColorAllBlack(BmpMap[i, j]) == false)
{
BmpMap[i, j].Save(fPath, ImageFormat.Png);
FrameMap[i, j].IsBlack = false;
} else
FrameMap[i, j].IsBlack = true;
BmpMap[i, j].Dispose();
}
}
}
public void SaveGroupToFiles(string outDirName, int nFile, int nCol, int nRow)
{
string fName = genFileName(nFile);
string fPath = outDirName + fName + "_" + nCol + "_" + nRow + ".png";
_frameGroupBmp.Save(fPath, ImageFormat.Png);
}
FrameGroup()
{
}
public FrameGroup(int resW, int resH, double sizeW, double sizeH, int nFramesHor, int nFramesVert, int nGroupHor, int nGroupVert)
{
_frameWidthPix = resW;
_frameHeightPix = resH;
_frameWidth = sizeW;
_frameHeight = sizeH;
_nFramesHor = nFramesHor;
_nFramesVert = nFramesVert;
_nGroupHor = nGroupHor;
_nGroupVert = nGroupVert;
// need to transfer this part into frame class !!!
_x0 = _frameWidth * nFramesHor * nGroupHor;
_y0 = _frameHeight * nFramesVert * nGroupVert;
// To make bricks: shift all frame groups to left in half of frame
_x0 -= _frameWidth / 2;
//if (nGroupVert % 2 == 1)
// _x0 -= _frameWidth / 2;
// To make bricks: extend width of frame group in half of frame
_rect = new RectDouble(_x0, _y0, GrpWidth + (_frameWidth / 2), GrpHeight);
_frameMap = new Frame[nFramesHor, nFramesVert];
for (int j = 0; j < nFramesVert; j++)
{
for (int i = 0; i < nFramesHor; i++)
{
_frameMap[i, j] = new Frame(resW, resH, sizeW, sizeH);
}
}
// Create just before drawing, then dispose
//_frameGroupBmp = new Bitmap(_fW * nFramesHor, _fH * nFramesVert);
}
public void FillByIntersectVoxelArcs(Strip[] _strips)
{
_rakurseArcs.Clear();
foreach (Strip strip in _strips)
{
if (strip.Empty == true)
continue;
foreach (Voxel voxel in strip.VoxelArray)
{
if (voxel.Empty == true)
continue;
foreach (RakurseArc arc in voxel.RakurseArcs)
{
if (arc.Radius == 0)
continue;
if (IntersectArc(arc))
{
_rakurseArcs.Add(arc);
}
}
}
}
}
// Reduce number of strips and voxels to process
public void ContainsVoxelRange(Treko3D.Treko3D treko3DObj)
{
double rectUpSide = this.Y0 - treko3DObj.RadiusMax;
double rectLeftSide = this.X0 - treko3DObj.RadiusMax;
double rectDownSide = this.Y0 + this.GrpHeight + treko3DObj.RadiusMax;
double rectRightSide = this.X0 + this.GrpWidth + treko3DObj.RadiusMax;
Bitmap RakurseBmp = treko3DObj.RakurseBmps[0];
treko3DObj.ImageHeightPix = RakurseBmp.Height;
treko3DObj.ImageWidthPix = RakurseBmp.Width;
_voxelRowRangeStart = (int)Math.Round(rectUpSide / treko3DObj.Step);
if (_voxelRowRangeStart < 0)
_voxelRowRangeStart = 0;
_voxelColRangeStart = (int)Math.Round(rectLeftSide / treko3DObj.Step);
if (_voxelColRangeStart < 0)
_voxelColRangeStart = 0;
_voxelRowRangeEnd = (int)Math.Round(rectDownSide / treko3DObj.Step);
if (_voxelRowRangeEnd > treko3DObj.ImageHeightPix)
_voxelRowRangeEnd = treko3DObj.ImageHeightPix;
_voxelColRangeEnd = (int)Math.Round(rectRightSide / treko3DObj.Step);
if (_voxelColRangeEnd > treko3DObj.ImageWidthPix)
_voxelColRangeEnd = treko3DObj.ImageWidthPix;
}
public void FillByIntersectVoxelArcs(Treko3D.Treko3D treko3DObj)
{
_rakurseArcs.Clear();
ContainsVoxelRange(treko3DObj);
//int nStrips = treko3DObj.RakurseBmps[0].Width;
//nStrips = 10;
//TraceTotalMemory.WriteTotalMemory(" FrameGroup, step 0");
for (int nStrip = _voxelRowRangeStart; nStrip < _voxelRowRangeEnd; nStrip++)
{
Strip strip = treko3DObj.GenerateStrip(nStrip, _voxelColRangeStart, _voxelColRangeEnd);
if (strip.Empty == true)
continue;
//TraceTotalMemory.WriteTotalMemory(" FrameGroup, step 1");
for (int nVoxel = _voxelColRangeStart; nVoxel < _voxelColRangeEnd; nVoxel++)
{
Voxel voxel = strip.VoxelArray[nVoxel];
if (voxel.Empty == true)
continue;
foreach (RakurseArc arc in voxel.RakurseArcs)
{
if (arc.Radius == 0)
continue;
if (IntersectArc(arc))
{
_rakurseArcs.Add(arc);
}
}
}
//TraceTotalMemory.WriteTotalMemory(" FrameGroup, step 2");
strip.Dispose();
strip = null;
//TraceTotalMemory.WriteTotalMemory(" FrameGroup, step 3");
}
}
// Reduce number of strips and voxels to process
public void ContainsColorRange(Treko.Treko trekoObj)
{
double rectUpSide = this.Y0 - trekoObj.RadiusMax;
double rectLeftSide = this.X0 - trekoObj.RadiusMax;
double rectDownSide = this.Y0 + this.GrpHeight + trekoObj.RadiusMax;
double rectRightSide = this.X0 + this.GrpWidth + trekoObj.RadiusMax;
Image ImgDisplayTreko = trekoObj.ImgDisplayTreko;
trekoObj.ImgDisplayTrekoHeightPix = ImgDisplayTreko.Height;
trekoObj.ImgDisplayTrekoWidthPix = ImgDisplayTreko.Width;
ColorPixelRowRangeStart = (int)Math.Round(rectUpSide / trekoObj.Step);
if (ColorPixelRowRangeStart < 0)
ColorPixelRowRangeStart = 0;
ColorPixelColRangeStart = (int)Math.Round(rectLeftSide / trekoObj.Step);
if (ColorPixelColRangeStart < 0)
ColorPixelColRangeStart = 0;
ColorPixelRowRangeEnd = (int)Math.Round(rectDownSide / trekoObj.Step);
if (ColorPixelRowRangeEnd > trekoObj.ImgDisplayTrekoHeightPix)
ColorPixelRowRangeEnd = trekoObj.ImgDisplayTrekoHeightPix;
ColorPixelColRangeEnd = (int)Math.Round(rectRightSide / trekoObj.Step);
if (ColorPixelColRangeEnd > trekoObj.ImgDisplayTrekoWidthPix)
ColorPixelColRangeEnd = trekoObj.ImgDisplayTrekoWidthPix;
}
public void FillByIntersectColorArcs(Treko.Treko trekoObj)
{
_colorArcs.Clear();
ContainsColorRange(trekoObj);
for (int nColorPixel = ColorPixelColRangeStart; nColorPixel < ColorPixelColRangeEnd; nColorPixel++)
{
//trekoObj.GenVectorData(_projectObj.HologramWidth, _projectObj.HologramHeight);
foreach (ColorPixel colorPixel in trekoObj.ColorPixels)
{
if (colorPixel == null)
continue;
if (colorPixel.ColorArcs == null || colorPixel.ColorArcs.Length == 0)
continue;
foreach (ColorArc arc in colorPixel.ColorArcs)
{
if (arc.Radius1 == 0)
continue;
if (IntersectArc(arc))
{
_colorArcs.Add(arc);
}
}
}
}
}
public void FillByIntersectColorArcs(ColorPixel[,] colorPixels)
{
_colorArcs.Clear();
foreach (ColorPixel colorPixel in colorPixels)
{
if (colorPixel == null)
continue;
if (colorPixel.ColorArcs == null || colorPixel.ColorArcs.Length == 0)
continue;
foreach (ColorArc arc in colorPixel.ColorArcs)
{
if (arc.Radius1 == 0)
continue;
if (IntersectArc(arc))
{
_colorArcs.Add(arc);
}
}
}
}
private void fillImageByBlack(Graphics gr)
{
Color col = Color.FromArgb(0, 0, 0);
gr.Clear(col);
}
public void DrawBitmapByRakurseArcs(int[] profileColor)
{
List<RakurseArc> arcs = IntersectRakurseArcs;
if (arcs == null || arcs.Count == 0)
{
_isBlack = true;
return;
}
else
{
_isBlack = false;
}
// extend for bricks
_frameGroupBmp = new Bitmap(GrpWidthPix + (_frameWidthPix / 2), GrpHeightPix);
//Pen whitePen = new Pen(Color.White, 2);
Graphics g = Graphics.FromImage(_frameGroupBmp); //.CreateGraphics();
fillImageByBlack(g);
foreach (RakurseArc arc in arcs)
{
arc.DrawArcInFrame(_rect, g, MmToPixelsCoeff, profileColor);
}
//whitePen.Dispose();
g.Dispose();
}
public void MarkFrameGroupAsBlack()
{
_isBlack = true;
}
public void DrawBitmapByColorArcs(int[] profileColor)
{
List<ColorArc> arcs = IntersectColorArcs;
if (arcs == null || arcs.Count == 0)
{
_isBlack = true;
return;
}
else
{
_isBlack = false;
}
// extend for bricks
_frameGroupBmp = new Bitmap(GrpWidthPix + (_frameWidthPix / 2), GrpHeightPix);
//_frameGroupBmp = new Bitmap(GrpWidthPix, GrpHeightPix);
//Pen whitePen = new Pen(Color.White, 2);
Graphics g = Graphics.FromImage(_frameGroupBmp); //.CreateGraphics();
fillImageByBlack(g);
foreach (ColorArc arc in arcs)
{
arc.DrawArcInFrame(_rect, g, MmToPixelsCoeff, profileColor);
}
//whitePen.Dispose();
g.Dispose();
}
public bool IntersectArc(RakurseArc arc)
{
if (_rect.IntersectWith(arc.RectCircumf) == true)
return true;
else
return false;
}
public bool Comparepoint(double compX, double compY)
{
if (compX > _x0 - 0.01 && compX < _x0 + _frameWidth + 0.01 && compY > _y0 - 0.01 && compY < _y0 + _frameHeight + 0.01)
return true;
else return false;
}
public bool IntersectArc(ColorArc arc)
{
return true; // !!!
//double CFx = _x0 + _frameWidth * _nFramesHor / 2;
//double CFy = _y0 + _frameHeight * _nFramesVert / 2;
////double CFx = _x0 + _frameWidth / 2;
////double CFy = _y0 + _frameHeight / 2;
//double AngFrame = Math.Abs(Math.Atan(Math.Sqrt((_frameWidth * _frameWidth + _frameHeight * _frameHeight) / 2 / (arc.X - CFx) * (arc.X - CFx) + (arc.Y - CFy) * (arc.Y - CFy))));
//double AngFrameS = Math.Atan2((CFy - arc.Y), (CFx - arc.X));
//for (double i = AngFrameS - AngFrame; i < AngFrameS + AngFrame; i += AngFrame / 2)
//{
// double compX = arc.X + Math.Cos(i) * arc.Radius1;
// double compY = arc.Y + Math.Sin(i) * arc.Radius1;
// if (Comparepoint(compX, compY) == true)
// return true;
//}
//return false;
//if (_rect.IntersectWith(arc.RectCircumf) == true)
// return true;
//else
// return false;
}
public void DrawBorder(Bitmap frameGroupBitmap, int mmToPixelsCoeff)
{
Pen whitePen = new Pen(Color.White, 2);
Graphics g = Graphics.FromImage(frameGroupBitmap); //.CreateGraphics();
_rect.DrawRectangleFromZeroCoord(g, whitePen, mmToPixelsCoeff);
whitePen.Dispose();
g.Dispose();
}
public void Dispose()
{
for (int i = 0; i < _rakurseArcs.Count; i++)
_rakurseArcs[i] = null;
_rakurseArcs.Clear();
_rakurseArcs = null;
if (BmpMap != null)
{
for (int i = 0; i < BmpMap.GetLength(0); i++)
for (int j = 0; j < BmpMap.GetLength(1); j++)
{
if (BmpMap[i, j] != null)
{
BmpMap[i, j].Dispose();
BmpMap[i, j] = null;
}
}
}
BmpMap = null;
if (_frameGroupBmp != null)
{
_frameGroupBmp.Dispose();
_frameGroupBmp = null;
}
}
}
#endregion
}