Loading files
This file is pinned to the selected release. Download the original to open it in your design tool.
5203ce801This file is pinned to the selected release. Download the original to open it in your design tool.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GerberLibrary;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;
//using System.Drawing.Drawing2D;
using GerberLibrary.Core.Primitives;
using GerberLibrary.Core;
using System.Drawing.Drawing2D;
using TriangleNet.Geometry;
using TriangleNet.IO;
using TriangleNet.Meshing;
using System.IO;
namespace GerberViewer
{
public class GerberVBO : GraphicsInterface
{
public struct VBOVertex
{
public float X, Y, Z;
public float DX, DY, DZ;
public float R, G, B, A;
public VBOVertex(float x, float y, float z, float dx, float dy, float dz, float r, float g, float b, float a)
{
X = x;
Y = y;
Z = z;
DX = dx;
DY = dy;
DZ = dz;
R = r;
G = g;
B = b;
A = a;
}
public const int Stride = 40;
}
private int ID_VBO = -1;
private List<VBOVertex> Vertices = new List<VBOVertex>(100000);
public void Reset()
{
Vertices.Clear();
if (ID_VBO > -1)
{
GL.DeleteBuffer(ID_VBO);
ID_VBO = -1;
}
}
int TheVertexCount = 0;
public void BuildVBO()
{
if (ID_VBO > -1)
{
GL.DeleteBuffer(ID_VBO);
ID_VBO = -1;
}
GL.GenBuffers(1, out ID_VBO);
GL.BindBuffer(BufferTarget.ArrayBuffer, ID_VBO);
GL.BufferData(BufferTarget.ArrayBuffer, (IntPtr)(Vertices.Count() * VBOVertex.Stride), Vertices.ToArray(), BufferUsageHint.StaticDraw);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
TheVertexCount = Vertices.Count();
Console.WriteLine("{0} vertices in the VBO!", Vertices.Count());
Vertices.Clear();
}
public void RenderVBO(ShaderProgram Shader)
{
if (ID_VBO < 0) return;
GL.EnableClientState(ArrayCap.VertexArray);
GL.BindBuffer(BufferTarget.ArrayBuffer, ID_VBO);
GL.EnableVertexAttribArray(Shader.Attributes["vPosition"].address);
GL.EnableVertexAttribArray(Shader.Attributes["vOff"].address);
GL.EnableVertexAttribArray(Shader.Attributes["vColor"].address);
GL.VertexAttribPointer(Shader.Attributes["vPosition"].address, 3, VertexAttribPointerType.Float, false, VBOVertex.Stride, 0);
GL.VertexAttribPointer(Shader.Attributes["vOff"].address, 3, VertexAttribPointerType.Float, false, VBOVertex.Stride, 4*3);
GL.VertexAttribPointer(Shader.Attributes["vColor"].address, 4 , VertexAttribPointerType.Float, false, VBOVertex.Stride, 4*6);
GL.DrawArrays(PrimitiveType.Triangles, 0, TheVertexCount);
GL.BindBuffer(BufferTarget.ArrayBuffer, 0);
}
RectangleF ClipRect;
public void SetupClipRect(float x, float y, float w, float h)
{
ClipRect = new RectangleF(x, y, w, h);
}
public RectangleF ClipBounds
{
get { return ClipRect; }
}
public static Matrix4 Mat4FromMat(System.Drawing.Drawing2D.Matrix inp)
{
Matrix4 M = Matrix4.Identity;
M.M11 = inp.Elements[0];
M.M12 = inp.Elements[1];
M.M21 = inp.Elements[2];
M.M22 = inp.Elements[3];
M[3, 0] = inp.OffsetX;
M[3, 1] = inp.OffsetY;
return M;
}
public CompositingMode CompositingMode { get { return CompositingMode.SourceCopy; } set {; }}
public System.Drawing.Drawing2D.InterpolationMode InterpolationMode { get { return System.Drawing.Drawing2D.InterpolationMode.Default; } set {; } }
public bool IsFast { get { return true; } set {; } }
private System.Drawing.Drawing2D.Matrix trans = new System.Drawing.Drawing2D.Matrix();
public System.Drawing.Drawing2D.Matrix Transform
{
get
{
return trans;
}
set
{
trans = value;
Matrix4 M = Mat4FromMat(trans);
GL.LoadIdentity();
GL.MultMatrix(ref M);
}
}
public bool Dotted
{
get; set;
}
public void Clear(Color color)
{
}
public void DrawImage(Bitmap MMGrid, float p1, float p2, float p3, float p4)
{
}
public void DrawLine(Pen P, PointF p1, PointF p2)
{
DrawLine(P, p1.X, p1.Y, p2.X, p2.Y);
}
public void DrawLine(Pen P, float x1, float y1, float x2, float y2)
{
float dx = x2 - x1;
float dy = y2 - y1;
float L = (float)Math.Sqrt(dx * dx + dy * dy);
if (L > 0)
{
float t = dx;
dx = -dy;
dy = t;
dx *= (float)( P.Width / (L*2.0f));
dx += 1;dx -= 1;
dy *=(float)( P.Width / (L*2.0f));
AddTriangleThick(x1, y1, dx, dy,
x2, y2, dx, dy,
x1, y1, -dx, -dy,
P.Color);
AddTriangleThick(x1, y1, -dx, -dy,
x2, y2, dx, dy,
x2, y2, -dx, -dy,
P.Color);
bool caps = false;
if (caps)
{
for (int i = 0; i < 6; i++)
{
float Ph = (float)(i * Math.PI) / 3.0f;
float S = (float)Math.Sin(Ph);
float C = (float)Math.Cos(Ph);
float Ph2 = (float)((i + 1) * Math.PI) / 3.0f;
float S2 = (float)Math.Sin(Ph2);
float C2 = (float)Math.Cos(Ph2);
AddTriangleThick(x1, y1, 0, 0,
x1, y1, S * P.Width, C * P.Width,
x1, y1, S2 * P.Width, C2 * P.Width,
P.Color);
AddTriangleThick(x2, y2, 0, 0,
x2, y2, S * P.Width, C * P.Width,
x2, y2, S2 * P.Width, C2 * P.Width,
P.Color);
}
}
}
}
public void AddTriangle(float x1, float y1, float x2, float y2, float x3, float y3, Color C)
{
Vertices.Add(new VBOVertex(x1, y1, 0, 0, 0, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
Vertices.Add(new VBOVertex(x2, y2, 0, 0, 0, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
Vertices.Add(new VBOVertex(x3, y3, 0, 0, 0, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
}
public void AddTriangleThick(float x1, float y1, float dx1, float dy1,
float x2, float y2, float dx2, float dy2,
float x3, float y3, float dx3, float dy3, Color C)
{
Vertices.Add(new VBOVertex(x1, y1, 0, dx1, dy1, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
Vertices.Add(new VBOVertex(x2, y2, 0, dx2, dy2, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
Vertices.Add(new VBOVertex(x3, y3, 0, dx3, dy3, 0, C.R / 255.0f, C.G / 255.0f, C.B / 255.0f, C.A / 255.0f));
}
public void DrawLines(Pen P, PointF[] Points)
{
for (int i = 0; i < Points.Length - 1; i++)
{
DrawLine(P, Points[i], Points[i + 1]);
}
}
public void DrawPath(Color black, GraphicsPath path, float v)
{
GraphicsPathIterator pathIterator = new GraphicsPathIterator(path);
//Rewind
// pathIterator.Rewind();
// Read all subpaths and their properties
for (int i = 0; i < pathIterator.SubpathCount; i++)
{
int strIdx, endIdx;
bool bClosedCurve;
pathIterator.NextSubpath(out strIdx, out endIdx, out bClosedCurve);
for (int j = strIdx; j < endIdx - 1; j++)
{
DrawLine(new Pen(black, v), path.PathPoints[j], path.PathPoints[j + 1]);
}
if (bClosedCurve)
{
DrawLine(new Pen(black, v), path.PathPoints[endIdx - 1], path.PathPoints[strIdx]);
}
}
}
public void DrawRectangle(Color color, float x, float y, float w, float h, float strokewidth = 1)
{
}
public void DrawString(string text, Font font, SolidBrush solidBrush, float x, float y, StringFormat sF)
{
}
internal int VertexCount()
{
return TheVertexCount;
}
public void DrawString(PointD pos, string text, double scale, bool centered, float r = 0.2F, float g = 0.2F, float b = 0.2F, float a = 1)
{
}
public void FillPath(Color c, PointF [] path)
{
var polygon = new Polygon();
List<TriangleNet.Geometry.Vertex> V = new List<TriangleNet.Geometry.Vertex>();
for (int j = 0; j < path.Length; j++)
{
V.Add(new TriangleNet.Geometry.Vertex(path[j].X, path[j].Y));
}
polygon.AddContour(V);
if (V.Count >= 3)
{
try
{
var options = new ConstraintOptions() { };
var quality = new QualityOptions() { };
var mesh = polygon.Triangulate(options, quality);
foreach (var t in mesh.Triangles)
{
var A = t.GetVertex(0);
var B = t.GetVertex(1);
var C = t.GetVertex(2);
AddTriangle((float)A.X, (float)A.Y, (float)B.X, (float)B.Y, (float)C.X, (float)C.Y, c);
}
}
catch(Exception)
{
}
}
}
public void DrawPath(Color c, PointF[] path, float v, bool bClosedCurve = true)
{
for (int j = 0; j < path.Length - 1; j++)
{
DrawLine(new Pen(c, v), path[j], path[j + 1]);
}
if (bClosedCurve)
{
DrawLine(new Pen(c, v), path[path.Length-1], path[0]);
}
}
public void FillPath(Color c, GraphicsPath path)
{
GraphicsPathIterator pathIterator = new GraphicsPathIterator(path);
var polygon = new Polygon();
for (int i = 0; i < pathIterator.SubpathCount; i++)
{
int strIdx, endIdx;
bool bClosedCurve;
pathIterator.NextSubpath(out strIdx, out endIdx, out bClosedCurve);
List<TriangleNet.Geometry.Vertex> V = new List<TriangleNet.Geometry.Vertex>();
for (int j = strIdx; j <= endIdx; j++)
{
V.Add(new TriangleNet.Geometry.Vertex(path.PathPoints[j].X, path.PathPoints[j].Y));
}
polygon.AddContour(V);
}
var options = new ConstraintOptions() { ConformingDelaunay = true };
var quality = new QualityOptions() { MinimumAngle = 25 };
var mesh = polygon.Triangulate(options, quality);
foreach (var t in mesh.Triangles)
{
var A = t.GetVertex(0);
var B = t.GetVertex(1);
var C = t.GetVertex(2);
AddTriangle((float)A.X, (float)A.Y, (float)B.X, (float)B.Y, (float)C.X, (float)C.Y, c);
}
}
public void FillPolygon(SolidBrush solidBrush, PointF[] pointF)
{
}
public void FillRectangle(Color color, float x, float y, float w, float h)
{
}
public void FillShape(SolidBrush BR, PolyLine Shape)
{
}
public PointD MeasureString(string p)
{
return new PointD(0, 0);
}
public void RotateTransform(float p)
{
}
public void ScaleTransform(float sx, float sy)
{
}
public void TranslateTransform(float p1, float p2)
{
}
public void FillTriangles(List<Triangle> triangles, Color C)
{
throw new NotImplementedException();
}
}
public class ShaderProgram
{
private int ProgramID;
private int VShaderID;
private int FShaderID;
private int AttributeCount;
private int UniformCount;
public Dictionary<String, AttributeInfo> Attributes = new Dictionary<string, AttributeInfo>();
public Dictionary<String, UniformInfo> Uniforms = new Dictionary<string, UniformInfo>();
public Dictionary<String, uint> Buffers = new Dictionary<string, uint>();
public ShaderProgram()
{
ProgramID = GL.CreateProgram();
}
public ShaderProgram(String vshader, String fshader, bool fromFile = false)
{
ProgramID = GL.CreateProgram();
if (fromFile)
{
LoadShaderFromFile(vshader, ShaderType.VertexShader);
LoadShaderFromFile(fshader, ShaderType.FragmentShader);
}
else
{
LoadShaderFromString(vshader, ShaderType.VertexShader);
LoadShaderFromString(fshader, ShaderType.FragmentShader);
}
Link();
// GenBuffers();
}
public class UniformInfo
{
public String name = "";
public int address = -1;
public int size = 0;
public ActiveUniformType type;
}
public class AttributeInfo
{
public String name = "";
public int address = -1;
public int size = 0;
public ActiveAttribType type;
}
private void loadShader(String code, ShaderType type, out int address)
{
address = GL.CreateShader(type);
GL.ShaderSource(address, code);
GL.CompileShader(address);
GL.AttachShader(ProgramID, address);
string L = GL.GetShaderInfoLog(address);
L = L.Trim();
if (L.Length > 0) Console.WriteLine(L);
}
public void LoadShaderFromString(String code, ShaderType type)
{
if (type == ShaderType.VertexShader)
{
loadShader(code, type, out VShaderID);
}
else if (type == ShaderType.FragmentShader)
{
loadShader(code, type, out FShaderID);
}
}
public void LoadShaderFromFile(String filename, ShaderType type)
{
using (StreamReader sr = new StreamReader(filename))
{
if (type == ShaderType.VertexShader)
{
loadShader(sr.ReadToEnd(), type, out VShaderID);
}
else if (type == ShaderType.FragmentShader)
{
loadShader(sr.ReadToEnd(), type, out FShaderID);
}
}
}
public void Link()
{
GL.LinkProgram(ProgramID);
Console.WriteLine(GL.GetProgramInfoLog(ProgramID));
GL.GetProgram(ProgramID, GetProgramParameterName.ActiveAttributes, out AttributeCount);
GL.GetProgram(ProgramID, GetProgramParameterName.ActiveUniforms, out UniformCount);
for (int i = 0; i < AttributeCount; i++)
{
AttributeInfo info = new AttributeInfo();
int length = 0;
String name;
GL.GetActiveAttrib(ProgramID, i, 256, out length, out info.size, out info.type, out name);
info.name = name.ToString();
info.address = GL.GetAttribLocation(ProgramID, info.name);
Attributes.Add(name.ToString(), info);
}
for (int i = 0; i < UniformCount; i++)
{
UniformInfo info = new UniformInfo();
int length = 0;
String name;
GL.GetActiveUniform(ProgramID, i, 256, out length, out info.size, out info.type, out name);
info.name = name.ToString();
Uniforms.Add(name.ToString(), info);
info.address = GL.GetUniformLocation(ProgramID, info.name);
}
}
internal void Bind()
{
GL.UseProgram(ProgramID);
}
internal void UnBind()
{
GL.UseProgram(0);
}
}
public class GLGraphicsInterface : GraphicsInterface
{
RectangleF ClipRect;
public GLGraphicsInterface(float x, float y, float w, float h)
{
ClipRect = new RectangleF(x, y, w, h);
}
public void Clear(Color color)
{
float r, g, b, a;
r = color.R / 255.0f;
g = color.G / 255.0f;
b = color.B / 255.0f;
a = color.A / 255.0f;
GL.ClearColor(r, g, b, a);
GL.Clear(ClearBufferMask.ColorBufferBit | ClearBufferMask.DepthBufferBit);
}
private System.Drawing.Drawing2D.Matrix trans = new System.Drawing.Drawing2D.Matrix();
public static Matrix4 Mat4FromMat(System.Drawing.Drawing2D.Matrix inp)
{
Matrix4 M =
Matrix4.Identity;
M.M11 = inp.Elements[0];
M.M12 = inp.Elements[1];
M.M21 = inp.Elements[2];
M.M22 = inp.Elements[3];
M[3, 0] = inp.OffsetX;
M[3, 1] = inp.OffsetY;
return M;
}
public System.Drawing.Drawing2D.Matrix Transform
{
get
{
return trans;
}
set
{
trans = value;
Matrix4 M = Mat4FromMat(trans);
GL.LoadIdentity();
GL.MultMatrix(ref M);
}
}
public RectangleF ClipBounds
{
get { return ClipRect; }
}
public void DrawImage(Bitmap MMGrid, float p1, float p2, float p3, float p4)
{
return;
}
public System.Drawing.Drawing2D.InterpolationMode InterpolationMode
{
get
{
return System.Drawing.Drawing2D.InterpolationMode.High;
}
set
{
}
}
public void DrawLines(Pen P, PointF[] Points)
{
GL.LineWidth(P.Width);
GL.Color4(P.Color.R, P.Color.G, P.Color.B, P.Color.A);
GL.Begin(BeginMode.LineStrip);
for (int i = 0; i < Points.Count(); i++)
{
GL.Vertex2(Points[i].X, Points[i].Y);
}
GL.End();
}
public void DrawLine(Pen P, float x1, float y1, float x2, float y2)
{
GL.LineWidth(P.Width);
GL.Color4(P.Color.R, P.Color.G, P.Color.B, P.Color.A);
GL.Begin(BeginMode.Lines);
GL.Vertex2(x1, y1);
GL.Vertex2(x2, y2);
GL.End();
}
void DoTransform(System.Drawing.Drawing2D.Matrix M)
{
trans.Multiply(M);
Transform = trans;
}
void DoTransform(Matrix4 M)
{
}
public void RotateTransform(float p)
{
System.Drawing.Drawing2D.Matrix M2 = new System.Drawing.Drawing2D.Matrix();
M2.Rotate(p);
DoTransform(M2);
}
public void ScaleTransform(float sx, float sy)
{
System.Drawing.Drawing2D.Matrix M2 = new System.Drawing.Drawing2D.Matrix();
M2.Scale(sx, sy);
DoTransform(M2);
}
public void TranslateTransform(float p1, float p2)
{
System.Drawing.Drawing2D.Matrix M2 = new System.Drawing.Drawing2D.Matrix();
M2.Translate(p1, p2);
DoTransform(M2);
}
public static System.Drawing.Drawing2D.Matrix MatFromMat4(Matrix4 M42)
{
System.Drawing.Drawing2D.Matrix R = new System.Drawing.Drawing2D.Matrix(M42.M11, M42.M12, M42.M21, M42.M22, M42[3, 0], M42[3, 1]);
return R;
}
public bool IsFast
{
get
{
return true;
}
set
{
// return false;
}
}
public CompositingMode CompositingMode
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
bool _Dotted;
public bool Dotted { get { return _Dotted; } set { _Dotted = value; }}
public void DrawString(PointD pos, string text, double scale, bool center, float r = 0.2f, float g = 0.2f, float b = 0.2f, float a = 1.0f)
{
}
private static void CheckFont()
{
}
public PointD MeasureString(string p)
{
return new PointD(1, 1);
}
public void FillShape(SolidBrush P, PolyLine Shape)
{
// GL.BlendFunc(BlendingFactorSrc.SrcAlpha, BlendingFactorDest.OneMinusSrcAlpha);
if (P.Color.A < 255)
{
GL.Enable(EnableCap.Blend);
}
var polygon = new Polygon();
List<Vertex> V = new List<Vertex>();
for (int i = 0; i < Shape.Count(); i++)
{
V.Add(new Vertex(Shape.Vertices[i].X, Shape.Vertices[i].Y));
}
polygon.AddContour(V);
var options = new ConstraintOptions() { ConformingDelaunay = true };
var quality = new QualityOptions() { MinimumAngle = 25 };
var mesh = polygon.Triangulate(options, quality);
GL.Begin(BeginMode.Triangles);
GL.Color4(P.Color.R, P.Color.G, P.Color.B, P.Color.A);
foreach (var t in mesh.Triangles)
{
var A = t.GetVertex(0);
var B = t.GetVertex(1);
var C = t.GetVertex(2);
GL.Vertex2(A.X, A.Y);
GL.Vertex2(B.X, B.Y);
GL.Vertex2(C.X, C.Y);
}
GL.End();
}
public void DrawLine(Pen P, PointF p1, PointF p2)
{
DrawLine(P, p1.X, p1.Y, p2.X, p2.Y);
}
public void DrawRectangle(Color color, float x, float y, float w, float h, float strokewidth = 1)
{
DrawLine(new Pen(color, strokewidth), x, y, x + w, y);
DrawLine(new Pen(color, strokewidth), x + w, y, x + w, y + h);
DrawLine(new Pen(color, strokewidth), x + w, y + h, x, y + h);
DrawLine(new Pen(color, strokewidth), x, y + h, x, y);
}
public void FillRectangle(Color color, float x, float y, float w, float h)
{
GL.Color4(color);
GL.Begin(BeginMode.Quads);
GL.Vertex2(x, y);
GL.Vertex2(x + w, y);
GL.Vertex2(x + w, y + h);
GL.Vertex2(x, y + h);
GL.End();
}
public void FillPath(Color c, GraphicsPath gP)
{
DrawPath(c, gP, 1.0f);
}
public void DrawString(string text, Font font, SolidBrush solidBrush, float x, float y, StringFormat sF)
{
// throw new NotImplementedException();
}
public void DrawPath(Color color, GraphicsPath path, float v)
{
GraphicsPathIterator pathIterator = new GraphicsPathIterator(path);
//Rewind
// pathIterator.Rewind();
GL.LineWidth(v);
// Read all subpaths and their properties
for (int i = 0; i < pathIterator.SubpathCount; i++)
{
int strIdx, endIdx;
bool bClosedCurve;
pathIterator.NextSubpath(out strIdx, out endIdx, out bClosedCurve);
GL.Begin(PrimitiveType.LineStrip);
GL.Color4(color.R, color.G, color.B, color.A);
for (int j = strIdx; j < endIdx; j++)
{
GL.Vertex2(path.PathPoints[j].X, path.PathPoints[j].Y);
}
if (bClosedCurve)
{
GL.Vertex2(path.PathPoints[strIdx].X, path.PathPoints[strIdx].Y);
}
GL.End();
}
}
public void FillPolygon(SolidBrush solidBrush, PointF[] pointF)
{
// throw new NotImplementedException();
}
internal Matrix4 GetGlMatrix()
{
return Mat4FromMat(trans);
}
public void FillTriangles(List<Triangle> triangles, Color C)
{
throw new NotImplementedException();
}
}
}