void SetXY(int x, int y) { lastX = x; lastY = y; if (Document.Gerbers.Count == 0) { return; } // if (Cache == null) return; PolyLineSet.Bounds Bounds = new PolyLineSet.Bounds(); foreach (var a in Document.Gerbers.OrderBy(xx => xx.sortindex)) { Bounds.AddBox(a.File.BoundingBox); } Graphics G = Graphics.FromImage(new Bitmap(1, 1)); float S = GetScaleAndBuildTransform(G, Bounds); var M = G.Transform.Clone(); M.Invert(); PointF[] P = new PointF[1] { new PointF(x, y) }; M.TransformPoints(P); MainForm.SetMouseCoord(P[0].X, P[0].Y); }
private float GetScaleAndBuildTransform(GraphicsInterface G2, PolyLineSet.Bounds Bounds) { Bitmap B = new Bitmap(1, 1); Graphics G = Graphics.FromImage(B); float S = GetScaleAndBuildTransform(G, Bounds); G2.Transform = G.Transform.Clone(); return(S); }
private void apictureBox1_Paint(object sender, PaintEventArgs e) { var G2 = e.Graphics; PolyLineSet.Bounds Bounds = new PolyLineSet.Bounds(); foreach (var a in Document.Gerbers.OrderBy(x => x.sortindex)) { Bounds.AddBox(a.File.BoundingBox); } if (Cache == null) { Cache = new Bitmap(Width, Height); Graphics G = Graphics.FromImage(Cache); GerberImageCreator.ApplyAASettings(G); GraphicsGraphicsInterface GGI = new GraphicsGraphicsInterface(G); GGI.Clear(Document.Colors.BackgroundColor); // DrawGerbersToGraphicsInterface(Bounds, GGI); } G2.DrawImage(Cache, 0, 0); GerberImageCreator.ApplyAASettings(G2); { if (Document.CrossHairActive) { if (Document.Gerbers.Count > 0) { float S = GetScaleAndBuildTransform(G2, Bounds); Color DimensionColor = Color.FromArgb(255, 255, 200); Pen P = new Pen(DimensionColor, 1.0f / S); P.DashPattern = new float[2] { 2, 2 }; G2.DrawLine(P, (float)Bounds.TopLeft.X - 1000, Document.MouseY, (float)Bounds.BottomRight.X + 1000, Document.MouseY); G2.DrawLine(P, (float)Document.MouseX, (float)Bounds.TopLeft.Y - 1000, (float)Document.MouseX, (float)Bounds.BottomRight.Y + 1000); DrawLabel(G2, String.Format("{0:N2}", Document.MouseX - Bounds.TopLeft.X), S, 12, DimensionColor, 5, 0, (float)Document.MouseX, (float)Bounds.TopLeft.Y, DisplaySide == BoardSide.Bottom); DrawLabel(G2, String.Format("{0:N2}", Document.MouseY - Bounds.TopLeft.Y), S, 12, DimensionColor, 0, -14, (float)Bounds.TopLeft.X, (float)Document.MouseY, DisplaySide == BoardSide.Bottom); //DrawUpsideDown(G2, String.Format("{0:N2}", Document.MouseX), S, 12, Color.Yellow, 5 / S + (float)Document.MouseX, (float)Bounds.TopLeft.Y); } } } }
public static PolyLineSet.Bounds GetBoundingBox(List <string> generatedFiles) { PolyLineSet.Bounds A = new PolyLineSet.Bounds(); foreach (var a in generatedFiles) { ParsedGerber PLS = PolyLineSet.LoadGerberFile(a, State: new GerberParserState() { PreCombinePolygons = false }); A.AddBox(PLS.BoundingBox); } return(A); }
private float GetScaleAndBuildTransform(Graphics G2, PolyLineSet.Bounds Bounds) { float S = 1; if (DisplaySide == BoardSide.Bottom) { S = Bounds.GenerateTransformWithScaleOffset(G2, Width, Height, 14, false, Zoomlevel, Offset); } else { S = Bounds.GenerateTransformWithScaleOffset(G2, Width, Height, 14, true, Zoomlevel, Offset); } return(S); }
internal Tuple <double, PolyLine> FindLargestPolygon() { if (OutlineShapes.Count == 0) { return(null); } List <Tuple <double, PolyLine> > Polies = new List <Tuple <double, PolyLine> >(); foreach (var a in OutlineShapes) { var area = Core.Helpers.PolygonSurfaceArea(a.Vertices); var bounds = new PolyLineSet.Bounds(); bounds.FitPoint(a.Vertices); Polies.Add(new Tuple <double, PolyLine>(bounds.Area(), a)); } return((from a in Polies orderby a.Item1 descending select a).First()); }
public PolyLineSet.Bounds GetOutlineBoundingBox() { PolyLineSet.Bounds B = new PolyLineSet.Bounds(); int i = 0; foreach (var a in PLSs) { if (a.Layer == BoardLayer.Mill || a.Layer == BoardLayer.Outline) { B.AddBox(a.BoundingBox); i++; } } if (i == 0) { return(BoundingBox); } return(B); }
public void CheckRelativeBoundingBoxes(ProgressLog Logger) { List <ParsedGerber> DrillFiles = new List <ParsedGerber>(); List <ParsedGerber> DrillFilesToReload = new List <ParsedGerber>(); PolyLineSet.Bounds BB = new PolyLineSet.Bounds(); foreach (var a in PLSs) { if (a.Layer == BoardLayer.Drill) { DrillFiles.Add(a); } else { BB.AddBox(a.BoundingBox); } } foreach (var a in DrillFiles) { if (a.BoundingBox.Intersects(BB) == false) { Errors.Add(String.Format("Drill file {0} does not seem to touch the main bounding box!", Path.GetFileName(a.Name))); if (Logger != null) { Logger.AddString(String.Format("Drill file {0} does not seem to touch the main bounding box!", Path.GetFileName(a.Name))); } PLSs.Remove(a); } } BoundingBox = new PolyLineSet.Bounds(); foreach (var a in PLSs) { // Console.WriteLine("Progress: Adding board {6} to box::{0:N2},{1:N2} - {2:N2},{3:N2} -> {4:N2},{5:N2}", a.BoundingBox.TopLeft.X, a.BoundingBox.TopLeft.Y, a.BoundingBox.BottomRight.X, a.BoundingBox.BottomRight.Y, a.BoundingBox.Width(), a.BoundingBox.Height(), Path.GetFileName(a.Name)); //Console.WriteLine("adding box for {0}:{1},{2}", a.Name, a.BoundingBox.Width(), a.BoundingBox.Height()); BoundingBox.AddBox(a.BoundingBox); } }
private static int FindNextClosest(List <PathDefWithClosed> Paths) { QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { B.FitPoint(Paths[i].Vertices.First()); B.FitPoint(Paths[i].Vertices.Last()); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start }, 5); Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End }, 5); } } RectangleF R = new RectangleF(); R.Width = 3; R.Height = 3; for (int i = 0; i < Paths.Count; i++) { var P = Paths[i]; if (P.Closed == false) { var PF = P.Vertices[0]; var PF2 = P.Vertices[1]; var PathDir = PF - PF2;// MathHelpers.Difference(PF, PF2); PathDir.Normalize(); R.X = (float)(P.Vertices.First().X - 1.5); R.Y = (float)(P.Vertices.First().Y - 1.5); int startmatch = -1; int endmatch = -1; double closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } if (P.Width != Paths[S.PathID].Width) { return(true); } PointD Dir2; if (S.Side == SideEnum.Start) { var S2 = Paths[S.PathID].Vertices[1]; Dir2 = S2 - S.Point; Dir2.Normalize(); } else { var S2 = Paths[S.PathID].Vertices[Paths[S.PathID].Vertices.Count() - 2]; Dir2 = S2 - S.Point; Dir2.Normalize(); } double dotted = Dir2.Dot(PathDir); var D = PointD.Distance(S.Point, PF); if (D < 1.0) { // D -= dotted * 3.0; if (D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { if (closestdistance > 0) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); } Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4a", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4a"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Reverse(); if (closestdistance > 0) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); } Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4b", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); //Console.WriteLine(" 4b"); return(1); } } PF = P.Vertices.Last(); R.X = (float)(P.Vertices.First().X - 1.5); R.Y = (float)(P.Vertices.First().Y - 1.5); startmatch = -1; endmatch = -1; closestdistance = B.Width() + B.Height(); Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } if (P.Width != Paths[S.PathID].Width) { return(true); } var D = PointD.Distance(S.Point, PF); if (D < 1.0 && D < closestdistance) { closestdistance = D; if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[i].Vertices.Reverse(); if (closestdistance > 0) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); } Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4c", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); // Console.WriteLine(" 4c"); return(1); } if (startmatch > -1) { if (closestdistance > 0) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); } Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 4d", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); // Console.WriteLine(" 4d"); return(1); } } } } return(0); }
private static int FindNextMerge(List <PathDefWithClosed> Paths, out int highestnomatch, int startat = 0) { highestnomatch = 0; QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = startat; i < Paths.Count; i++) { if (Paths[i].Closed == false) { B.FitPoint(Paths[i].Vertices.First()); B.FitPoint(Paths[i].Vertices.Last()); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; for (int i = startat; i < Paths.Count; i++) { if (Paths[i].Closed == false) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.First(), Side = SideEnum.Start }, 4); Root.Insert(new SegmentEndContainer() { PathID = i, Point = Paths[i].Vertices.Last(), Side = SideEnum.End }, 4); } } RectangleF R = new RectangleF(); R.Width = 10; R.Height = 10; for (int i = startat; i < Paths.Count; i++) { // Console.WriteLine("checking path {0}", i); var P = Paths[i]; if (P.Closed == false) { var PF = P.Vertices.First(); // Console.WriteLine("checking firstvert {0}", PF); R.X = (float)(P.Vertices.First().X - 5); R.Y = (float)(P.Vertices.First().Y - 5); int startmatch = -1; int endmatch = -1; Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } // Console.WriteLine(" against {0}", S.Point); if (S.Point == PF) { if (S.Side == SideEnum.Start) { startmatch = S.PathID; // Console.WriteLine(" matched start {0}" , startmatch); } else { endmatch = S.PathID; // Console.WriteLine(" matched end {0}", endmatch); } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3a", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); //Console.WriteLine(" a"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Reverse(); Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3b", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); // Console.WriteLine(" b"); return(1); } } PF = P.Vertices.Last(); // Console.WriteLine("checking lastvert {0}", PF); R.X = (float)(P.Vertices.First().X - 5); R.Y = (float)(P.Vertices.First().Y - 5); startmatch = -1; endmatch = -1; Root.CallBackInside(R, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.PathID == i) { return(true); } // Console.WriteLine(" against {0}", S.Point); if (S.Point == PF) { if (S.Side == SideEnum.Start) { startmatch = S.PathID; } else { endmatch = S.PathID; } } return(true); }); if (startmatch > -1 || endmatch > -1) { if (endmatch > -1) { Paths[i].Vertices.Reverse(); Paths[endmatch].Vertices.Remove(Paths[endmatch].Vertices.Last()); Paths[endmatch].Vertices.AddRange(Paths[i].Vertices); if (Paths[endmatch].Vertices.First() == Paths[endmatch].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3c", Paths[endmatch].Vertices.Count()); Paths[endmatch].Closed = true; } Paths.Remove(Paths[i]); //Console.WriteLine(" c"); return(1); } if (startmatch > -1) { Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); Paths[i].Vertices.AddRange(Paths[startmatch].Vertices); if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) { Console.WriteLine("closed path with {0} points during stage 3d", Paths[i].Vertices.Count()); Paths[i].Closed = true; } Paths.Remove(Paths[startmatch]); //Console.WriteLine(" d"); return(1); } } highestnomatch = i; } } return(0); //for (int i = 0; i < Paths.Count; i++) //{ // for (int j = i + 1; j < Paths.Count; j++) // { // if (Paths[i].Closed == false && Paths[j].Closed == false) // { // if (Paths[j].Vertices.First() == Paths[i].Vertices.Last()) // { // Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); // Paths[i].Vertices.AddRange(Paths[j].Vertices); // if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true; // Paths.Remove(Paths[j]); // return 1; // } // else // { // if (Paths[i].Vertices.First() == Paths[j].Vertices.Last()) // { // Paths[j].Vertices.Remove(Paths[j].Vertices.Last()); // Paths[j].Vertices.AddRange(Paths[i].Vertices); // if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true; // Paths.Remove(Paths[i]); // return 1; // } // else // { // if (Paths[i].Vertices.First() == Paths[j].Vertices.First()) // { // Paths[i].Vertices.Reverse(); // Paths[i].Vertices.Remove(Paths[i].Vertices.Last()); // Paths[i].Vertices.AddRange(Paths[j].Vertices); // if (Paths[i].Vertices.First() == Paths[i].Vertices.Last()) Paths[i].Closed = true; // Paths.Remove(Paths[j]); // return 1; // } // else // if (Paths[i].Vertices.Last() == Paths[j].Vertices.Last()) // { // Paths[i].Vertices.Reverse(); // Paths[j].Vertices.Remove(Paths[j].Vertices.Last()); // Paths[j].Vertices.AddRange(Paths[i].Vertices); // if (Paths[j].Vertices.First() == Paths[j].Vertices.Last()) Paths[j].Closed = true; // Paths.Remove(Paths[i]); // return 1; // } // } // } // } // } //} //return 0; }
public static List <PathDefWithClosed> LineSegmentsToPolygons(List <PathDefWithClosed> input, bool joinclosest = true) { // return input; List <PathDefWithClosed> Paths = new List <PathDefWithClosed>(); List <PathDefWithClosed> FirstSweep = new List <PathDefWithClosed>(); List <PathDefWithClosed> LeftoverLines = new List <PathDefWithClosed>(); if (input.Count == 0) { return(LeftoverLines); } try { foreach (var p in input) { if (p.Vertices.Count() > 0) { FirstSweep.Add(Sanitize(p)); } } FirstSweep = StripOverlaps(FirstSweep); LeftoverLines.Add(FirstSweep[0]); for (int i = 1; i < FirstSweep.Count; i++) { var LastLeft = LeftoverLines.Last(); var LastLeftP = LastLeft.Vertices.Last(); if (FirstSweep[i].Vertices.First() == LastLeftP) { LastLeft.Vertices.AddRange(FirstSweep[i].Vertices.Skip(1)); } else { if (FirstSweep[i].Vertices.Last() == LastLeftP) { FirstSweep[i].Vertices.Reverse(); LastLeft.Vertices.AddRange(FirstSweep[i].Vertices.Skip(1)); } else { LeftoverLines.Add(FirstSweep[i]); } } } LeftoverLines = StripOverlaps(LeftoverLines); } catch (Exception E) { Console.WriteLine(E.Message); } while (LeftoverLines.Count > 0) { bool added = false; var a = LeftoverLines.Last(); LeftoverLines.Remove(a); if (added == false) { PathDefWithClosed P = new PathDefWithClosed(); P.Width = a.Width; foreach (var v in a.Vertices) { P.Vertices.Add(v); } //P.Points.Add(a.Last()); if (a.Vertices.First() == a.Vertices.Last()) { int matching = 0; for (int i = 0; i < a.Vertices.Count / 2; i++) { if (a.Vertices[i] == a.Vertices[a.Vertices.Count - 1 - i]) { matching++; } } if (matching > 1) { P.Vertices.Clear(); List <PointD> DebugN = new List <PointD>(); List <int> Kinks = new List <int>(); List <int> KinkEnd = new List <int>(); Kinks.Add(0); for (int i = 1; i < a.Vertices.Count; i++) { var N1 = MathHelpers.Normal(a.Vertices[(i - 1)], a.Vertices[i]); var N2 = MathHelpers.Normal(a.Vertices[i], a.Vertices[(i + 1) % a.Vertices.Count()]); if (N1.Dot(N2) < 0.8) { DebugN.Add(a.Vertices[i]); DebugN.Add(N1 * 4.0 + a.Vertices[i]); Kinks.Add(i); KinkEnd.Add(i); } } KinkEnd.Add(a.Vertices.Count - 1); double maxD = 0; int maxSeg = 0; for (int i = 0; i < Kinks.Count; i++) { double D = 0; for (int j = Kinks[i]; j < KinkEnd[i]; j++) { D += (a.Vertices[j] - a.Vertices[j + 1]).Length(); } if (D > maxD) { maxD = D; maxSeg = i; } } for (int i = Kinks[maxSeg]; i < KinkEnd[maxSeg]; i++) { P.Vertices.Add(a.Vertices[i]); } bool dumpdebugline = false; if (dumpdebugline) { PolyLineSet.Bounds Bbox = new PolyLineSet.Bounds(); foreach (var v in a.Vertices) { Bbox.FitPoint(v); Bbox.FitPoint(new PointD(v.X + 10, v.Y + 10)); Bbox.FitPoint(new PointD(v.X - 10, v.Y - 10)); } float Scaler = 50.0f; Bitmap OutB = new Bitmap((int)(Bbox.Width() * Scaler), (int)(Bbox.Height() * Scaler)); Graphics G = Graphics.FromImage(OutB); G.Clear(Color.White); GraphicsGraphicsInterface GGI = new GraphicsGraphicsInterface(G); GGI.TranslateTransform((float)-Bbox.TopLeft.X * Scaler, (float)-Bbox.TopLeft.Y * Scaler); GGI.DrawLines(new Pen(Color.Red, 0.1f), (from i in a.Vertices select(i * Scaler).ToF()).ToArray()); for (int i = 1; i < a.Vertices.Count; i++) { var N = MathHelpers.Normal(a.Vertices[i - 1], a.Vertices[i]); GGI.DrawString(i.ToString(), new Font("arial", 14), new SolidBrush(Color.FromArgb((i + 128) % 256, i % 256, i % 256)), (float)a.Vertices[i].X * Scaler + (float)N.X * 20.0f, (float)a.Vertices[i].Y * Scaler + (float)N.Y * 20.0f, new StringFormat()); } for (int i = 0; i < DebugN.Count; i += 2) { GGI.DrawLine(new Pen(Color.DarkGreen, 1.0f), (DebugN[i] * Scaler).ToF(), (DebugN[i + 1] * Scaler).ToF()); } OutB.Save("testout.png"); } } else { a.Vertices.Remove(a.Vertices.Last()); //Console.WriteLine("closed path with {0} points during stage 2: {1} reversematched", a.Vertices.Count(), matching); P.Closed = true; } } Paths.Add(P); } } Paths = StripOverlaps(Paths); // return Paths; int Merges = 1; int startat = 0; int lasthigh = 0; while (Merges > 0) { startat = lasthigh; Merges = FindNextMerge(Paths, out lasthigh, startat); } //return Paths; int ClosedCount = (from i in Paths where i.Closed == true select i).Count(); if (ClosedCount < Paths.Count) { //Console.WriteLine("{0}/{1} paths open - finding closest connections", Paths.Count - ClosedCount, Paths.Count); if (joinclosest) { Merges = 1; while (Merges > 0) { Merges = FindNextClosest(Paths); } int NewClosedCount = (from i in Paths where i.Closed == true select i).Count(); Console.WriteLine("remaining open: {0}", NewClosedCount); /* * var OpenPaths = (from i in Paths where i.Closed == false select i).ToArray(); * // foreach (var p in OpenPaths) * // { * // Paths.Remove(p); * // } * * while (OpenPaths.Count() > 1) * { * var P = OpenPaths[0]; * var V = P.Points.Last(); * double ClosestDistance = 1000000; * int closestindex = 0; * bool forward = true; * * double OwnDistance = (P.Points.First() - P.Points.Last()).Length(); * ClosestDistance = OwnDistance; * for (int i = 1; i < OpenPaths.Count(); i++) * { * double dx1 = OpenPaths[i].Points.First().X - V.X; * double dy1 = OpenPaths[i].Points.First().Y - V.Y; * * double dx2 = OpenPaths[i].Points.Last().X - V.X; * double dy2 = OpenPaths[i].Points.Last().Y - V.Y; * * float disttofirst = (float)Math.Sqrt(dx1 * dx1 + dy1 * dy1); * float disttolast = (float)Math.Sqrt(dx2 * dx2 + dy2 * dy2); * * if (disttofirst < ClosestDistance) * { * forward = true; * closestindex = i; * ClosestDistance = disttofirst; * } * * if (disttolast < ClosestDistance) * { * forward = false; * closestindex = i; * ClosestDistance = disttolast; * } * * } * if (OwnDistance == ClosestDistance) * { * P.Closed = true; * // Paths.Add(P); * } * else * { * if (forward) * { * var PJ = OpenPaths[closestindex]; * P.Points.AddRange(PJ.Points); * Paths.Remove(PJ); * } * else * { * var PJ = OpenPaths[closestindex]; * PJ.Points.Reverse(); * P.Points.AddRange(PJ.Points); * Paths.Remove(PJ); * } * if (P.Points.First() == P.Points.Last()) * { * P.Closed = true; * } * } * * * OpenPaths = (from i in Paths where i.Closed == false select i).ToArray(); * * }*/ } } List <PathDefWithClosed> Results = new List <PathDefWithClosed>(); foreach (var p in Paths) { Results.Add(Sanitize(p)); } return(Results); }
private static List <PathDefWithClosed> StripOverlaps(List <PathDefWithClosed> Paths) { List <PathDefWithClosed> Res = new List <PathDefWithClosed>(); QuadTreeNode Root = new QuadTreeNode(); PolyLineSet.Bounds B = new PolyLineSet.Bounds(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { foreach (var a in Paths[i].Vertices) { B.FitPoint(a); } } else { Res.Add(Paths[i]); } } Root.xstart = B.TopLeft.X - 10; Root.xend = B.BottomRight.X + 10; Root.ystart = B.TopLeft.Y - 10; Root.yend = B.BottomRight.Y + 10; RectangleF QueryRect = new RectangleF(); QueryRect.Width = 3; QueryRect.Height = 3; List <PathDefWithClosed> ToDelete = new List <PathDefWithClosed>(); for (int i = 0; i < Paths.Count; i++) { if (Paths[i].Closed == false) { int nearcount = 0; foreach (var a in Paths[i].Vertices) { QueryRect.X = (float)a.X - 1.5f; QueryRect.Y = (float)a.Y - 1.5f; Root.CallBackInside(QueryRect, delegate(QuadTreeItem QI) { var S = QI as SegmentEndContainer; if (S.Point == a) { nearcount++; } else { if (PointD.Distance(a, S.Point) < 0.001) { nearcount++; } } return(true); } ); } int max = Math.Max(4, (Paths[i].Vertices.Count * 50) / 100); if (nearcount <= max) { foreach (var a in Paths[i].Vertices) { Root.Insert(new SegmentEndContainer() { PathID = i, Point = a, Side = SideEnum.Start }, 8); } Res.Add(Paths[i]); } else { Res.Add(Paths[i]); Console.WriteLine("{4}: {0} out of {1}/{2}/{3}", nearcount, max, Paths[i].Vertices.Count, (Paths[i].Vertices.Count * 90) / 100, i); Console.WriteLine("{0}: skipped!", i); } } } return(Res); }
private void DrawGerbersToGraphicsInterface(PolyLineSet.Bounds Bounds, GerberVBO GGI) { if (Document.Gerbers.Count > 0) { float S = GetScaleAndBuildTransform(GGI, Bounds); if (DispGerb == null) { if (DisplaySide == BoardSide.Bottom) { foreach (var a in Document.Gerbers.OrderByDescending(x => x.sortindex)) { if (a.File.Layer != BoardLayer.Drill) { var C = Color.FromArgb(100, a.Color); if (a.File.Side == BoardSide.Top) { C = MathHelpers.Interpolate(C, Document.Colors.BackgroundColor, 0.4f); } DrawGerber(GGI, a.File, C); } } } else { foreach (var a in Document.Gerbers.OrderBy(x => x.sortindex)) { if (a.File.Layer != BoardLayer.Drill) { var C = a.Color; if (a.File.Side == BoardSide.Bottom) { C = MathHelpers.Interpolate(C, Document.Colors.BackgroundColor, 0.4f); } DrawGerber(GGI, a.File, C); } } } foreach (var a in Document.Gerbers.OrderBy(x => x.sortindex)) { if (a.File.Layer == BoardLayer.Drill) { DrawGerber(GGI, a.File, a.Color); } } } else { foreach (var a in Document.Gerbers.OrderBy(x => x.sortindex)) { if (a.File.Layer == BoardLayer.Outline || a.File.Layer == BoardLayer.Mill) { DrawGerber(GGI, a.File, Color.FromArgb(20, 255, 255, 255), true); } } DrawGerber(GGI, DispGerb.File, Color.White); } } }
private void Glcontrol1_Paint(object sender, PaintEventArgs e) { if (!glLoaded) { return; } PolyLineSet.Bounds Bounds = new PolyLineSet.Bounds(); foreach (var a in Document.Gerbers.OrderBy(x => x.sortindex)) { Bounds.AddBox(a.File.BoundingBox); } if (VBOCacheDirty) { VBOCache.Reset(); DrawGerbersToGraphicsInterface(Bounds, VBOCache); // VBOCache.DrawLine(new Pen(Color.White, 1), Bounds.TopLeft.ToF(), Bounds.BottomRight.ToF()); VBOCache.BuildVBO(); VBOCacheDirty = false; } GLGraphicsInterface GI = new GLGraphicsInterface(0, 0, Width, Height); glcontrol1.MakeCurrent(); GL.MatrixMode(MatrixMode.Projection); GL.LoadIdentity(); GL.Disable(EnableCap.CullFace); GL.Ortho(0, glcontrol1.Width, glcontrol1.Height, 0, -100, 100); GL.LineWidth(1.0f); //GL.Scale(0.01, 0.01, 1); GL.MatrixMode(MatrixMode.Modelview); GL.LoadIdentity(); GL.Viewport(0, 0, glcontrol1.Width, glcontrol1.Height); Matrix4 View = Matrix4.CreateOrthographicOffCenter(0, glcontrol1.Width, glcontrol1.Height, 0, -100, 100); // GI.Clear(Color.Yellow); GI.Clear(Document.Colors.BackgroundColor); // GGI.Clear(Document.Colors.BackgroundColor); float S = GetScaleAndBuildTransform(GI, Bounds); MainShader.Bind(); var M = GI.GetGlMatrix(); GL.Uniform1(MainShader.Uniforms["linescale"].address, 1.0f / S); GL.UniformMatrix4(MainShader.Uniforms["trans"].address, false, ref M); GL.UniformMatrix4(MainShader.Uniforms["view"].address, false, ref View); GL.Enable(EnableCap.Blend); GL.BlendFunc(BlendingFactor.SrcAlpha, BlendingFactor.OneMinusSrcAlpha); VBOCache.RenderVBO(MainShader); MainShader.UnBind(); //DrawGerbersToGraphicsInterface(Bounds, GI); { if (Document.CrossHairActive) { if (Document.Gerbers.Count > 0) { float S2 = GetScaleAndBuildTransform(GI, Bounds); Color DimensionColor = Color.FromArgb(255, 255, 200); Pen P = new Pen(DimensionColor, 1.0f); P.DashPattern = new float[2] { 2, 2 }; GI.DrawLine(P, (float)Bounds.TopLeft.X - 1000, Document.MouseY, (float)Bounds.BottomRight.X + 1000, Document.MouseY); GI.DrawLine(P, (float)Document.MouseX, (float)Bounds.TopLeft.Y - 1000, (float)Document.MouseX, (float)Bounds.BottomRight.Y + 1000); //DrawLabel(G2, String.Format("{0:N2}", Document.MouseX - Bounds.TopLeft.X), S, 12, DimensionColor, 5, 0, (float)Document.MouseX, (float)Bounds.TopLeft.Y, DisplaySide == BoardSide.Bottom); //DrawLabel(G2, String.Format("{0:N2}", Document.MouseY - Bounds.TopLeft.Y), S, 12, DimensionColor, 0, -14, (float)Bounds.TopLeft.X, (float)Document.MouseY, DisplaySide == BoardSide.Bottom); //DrawUpsideDown(G2, String.Format("{0:N2}", Document.MouseX), S, 12, Color.Yellow, 5 / S + (float)Document.MouseX, (float)Bounds.TopLeft.Y); } } } glcontrol1.SwapBuffers(); }
public void FixEagleDrillExportIssues(ProgressLog Logger) { List <ParsedGerber> DrillFiles = new List <ParsedGerber>(); List <Tuple <double, ParsedGerber> > DrillFilesToReload = new List <Tuple <double, ParsedGerber> >(); PolyLineSet.Bounds BB = new PolyLineSet.Bounds(); foreach (var a in PLSs) { if (a.Layer == BoardLayer.Drill) { DrillFiles.Add(a); } else { BB.AddBox(a.BoundingBox); } } foreach (var a in DrillFiles) { var b = a.BoundingBox; if (b.Width() > BB.Width() * 1.5 || b.Height() > BB.Height() * 1.5) { var MaxRatio = Math.Max(b.Width() / BB.Width(), b.Height() / BB.Height()); if (Logger != null) { Logger.AddString(String.Format("Note: Really large drillfile found({0})-fix your export scripts!", a.Name)); } Console.WriteLine("Note: Really large drillfile found ({0})- fix your export scripts!", a.Name); DrillFilesToReload.Add(new Tuple <double, ParsedGerber>(MaxRatio, a)); } } foreach (var a in DrillFilesToReload) { PLSs.Remove(a.Item2); var scale = 1.0; if (Double.IsInfinity(a.Item1) || Double.IsNaN(a.Item1)) { Errors.Add("Drill file size reached infinity - ignoring it"); if (Logger != null) { Logger.AddString("Drill file size reached infinity - ignoring it"); } } else { var R = a.Item1; while (R >= 1.5) { R /= 10; scale /= 10; } AddFileToSet(a.Item2.Name, Logger, scale); } } BoundingBox = new PolyLineSet.Bounds(); foreach (var a in PLSs) { //Console.WriteLine("Progress: Adding board {6} to box::{0:N2},{1:N2} - {2:N2},{3:N2} -> {4:N2},{5:N2}", a.BoundingBox.TopLeft.X, a.BoundingBox.TopLeft.Y, a.BoundingBox.BottomRight.X, a.BoundingBox.BottomRight.Y, a.BoundingBox.Width(), a.BoundingBox.Height(), Path.GetFileName( a.Name)); //Console.WriteLine("adding box for {0}:{1},{2}", a.Name, a.BoundingBox.Width(), a.BoundingBox.Height()); BoundingBox.AddBox(a.BoundingBox); } }