Example #1
0
        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);
        }
Example #2
0
        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);
        }
Example #3
0
        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);
                    }
                }
            }
        }
Example #4
0
        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);
        }
Example #5
0
        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);
        }
Example #6
0
        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());
        }
Example #7
0
        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);
        }
Example #8
0
        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);
            }
        }
Example #9
0
        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);
        }
Example #10
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;
        }
Example #11
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);
        }
Example #12
0
        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);
        }
Example #13
0
        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);
                }
            }
        }
Example #14
0
        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();
        }
Example #15
0
        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);
            }
        }