Beispiel #1
0
            public string ToString(double x, double y)
            {
                Int32 SA = Convert.ToInt32(StartAngle * 100);
                Int32 EA = Convert.ToInt32(EndAngle * 100);

                if (Math.Abs(EA - SA) == 36000)
                {
                    // it's a circle
                    return($"    (fp_circle (center {Math.Round(X1 - x, Precision)} {Math.Round(-(Y1 - y), Precision)}) (end {Math.Round(X1+Radius - x, Precision)} {Math.Round(-(Y1 - y), Precision)}) (layer {Layer}) (width {Width}))\n");
                }
                else
                {
                    double Xs, Ys, Xe, Ye;
                    Xs    = Math.Round((X1 - x) + Radius * Math.Cos(Radians(StartAngle)), Precision);
                    Ys    = Math.Round((Y1 - y) + Radius * Math.Sin(Radians(StartAngle)), Precision);
                    Xe    = Math.Round((X1 - x) + Radius * Math.Cos(Radians(EndAngle)), Precision);
                    Ye    = Math.Round((Y1 - y) + Radius * Math.Sin(Radians(EndAngle)), Precision);
                    Width = Math.Round(Width, Precision);
                    CheckMinMax(Xs, Ys);
                    CheckMinMax(Xe, Xe);
                    var           arc    = new StringBuilder("");
                    string        n      = (net == -1) ? "" : $"net {net}";
                    List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer));
                    foreach (var L in Layers)
                    {
                        arc.Append($"    (arc (start {Xs} {-Ys}) (end {Xe} {Ye}) (angle {Math.Round(EndAngle-StartAngle, Precision)}) (layer {L}) (width {Width}))\n");
                    }
                    return(arc.ToString());
                }
            }
Beispiel #2
0
            public override string ToString()
            {
                string StartL = Brd.GetLayer(StartLayer);
                string EndL   = Brd.GetLayer(EndLayer);
                string blind  = ((StartL != "F.Cu") || (EndL != "B.Cu")) ? "blind" : "";

                return($"  (via {blind} (at {Math.Round(X, Precision)} {Math.Round(-Y, Precision)}) (size {Size}) (drill {Drill}) (layers {StartL} {EndL}) (net {Net}))\n");
            }
Beispiel #3
0
            public override string ToString()
            {
                var    ret          = new StringBuilder("");
                string connectstyle = "";

                double clearance = GetRuleValue(this, "Clearance", "PolygonClearance");

                if (Layer.Substring(0, 2) == "In")
                {
                    // this is an inner layer so use plane clearance
                    clearance = GetRuleValue(this, "PlaneClearance", "PlaneClearance");
                }
                List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer));

                foreach (var L in Layers)
                {
                    ret.Append($"  (zone (net {NetNo}) (net_name {NetName}) (layer {L}) (hatch edge 0.508)");
                    ret.Append($"    (priority {GetPriority(PourIndex)})\n");
                    ret.Append($"    (connect_pads {connectstyle} (clearance {clearance}))\n"); // TODO sort out these numbers properly
                    ret.Append($"    (min_thickness {NeckWidthThreshold})\n");
                    ret.Append("    (fill yes (arc_segments 16) (thermal_gap 0.2) (thermal_bridge_width 0.3))\n");
                    var i = 0;
                    ret.Append("    (polygon (pts\n        ");
                    foreach (var Point in Points)
                    {
                        i++;
                        if ((i % 5) == 0)
                        {
                            ret.Append("\n        ");
                        }
                        ret.Append(Point.ToString());
                        CheckMinMax(Point.X, Point.Y);
                    }
                    ret.Append("\n      )\n    )\n  )\n");
                    if (IsSplitPlane)
                    {
                        ret.Append("# Split Plane\n");
                    }
                }

                return(ret.ToString());
            }
Beispiel #4
0
            public override string ToString(double x, double y, double ModuleRotation)
            {
                Point2D p1 = new Point2D(X1 - x, Y1 - y);

                double  X2 = (X1 - x) + Radius * Math.Cos(Radians(StartAngle));
                double  Y2 = (Y1 - y) + Radius * Math.Sin(Radians(StartAngle));
                Point2D p2 = new Point2D(X2, Y2);

                p1.Rotate(ModuleRotation);
                p2.Rotate(ModuleRotation);

                Int32 SA = Convert.ToInt32(StartAngle * 100);
                Int32 EA = Convert.ToInt32(EndAngle * 100);

                if (Math.Abs(EA - SA) == 36000)
                {
                    // it's a circle
                    StringBuilder circle = new StringBuilder("");
                    List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer));
                    foreach (var L in Layers)
                    {
                        circle.Append($"    (fp_circle (center {p1.X} {-p1.Y}) (end {p2.X} {-p2.Y}) (layer {L}) (width {Width}))\n");
                    }
                    return(circle.ToString());
                }
                else
                {
                    StringBuilder arc    = new StringBuilder("");
                    List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer));
                    foreach (var L in Layers)
                    {
                        arc.Append($"    (fp_arc (start {Math.Round(p1.X, Precision)} {Math.Round(-p1.Y, Precision)}) (end {Math.Round(p2.X, Precision)} {Math.Round(-p2.Y, Precision)}) (angle {Math.Round(-(EndAngle - StartAngle), Precision)}) (layer {L}) (width {Width}))\n");
                    }
                    return(arc.ToString());;
                }
            }
Beispiel #5
0
            public Polygon(string line) // string Layer, int net)
            {
                string param;

                ObjectType = PCBObjectType.Polygon;
                Int32 net = 0;

                if ((param = GetString(line, "|NET=")) != "")
                {
                    net = Convert.ToInt32(param) + 1;
                }
                string Net = GetNetName(net);

                if ((param = GetString(line, "|COMPONENT=")) != "")
                {
                    Component   = Convert.ToInt32(param);
                    InComponent = true;
                }
                if ((param = GetString(line, "|LAYER=")) != "")
                {
                    Layer = Brd.GetLayer(param);
                }
                IsSplitPlane = ((param = GetString(line, "|POLYGONTYPE=")) == "Split Plane");
                if (!IsSplitPlane && (param = GetString(line, "|TRACKWIDTH=")) != "")
                {
                    TrackWidth = Convert.ToDouble(GetNumberInMM(param));
                }
                else
                {
                    TrackWidth         = 0.1; // maybe should be smaller for split plane
                    NeckWidthThreshold = 0.1;
                }
                if ((param = GetString(line, "|POURINDEX=")) != "")
                {
                    PourIndex = Convert.ToInt16(param);
                    if (PourIndex > Brd.MaxPourIndex)
                    {
                        Brd.MaxPourIndex = PourIndex;
                    }
                }

                if ((param = GetString(line, "|NECKWIDTHTHRESHOLD=")) != "")
                {
                    NeckWidthThreshold = GetNumberInMM(param.Trim(charsToTrim));
                }

                NetNo   = net;
                NetName = GetNetName(NetNo);
                Points  = new List <Point>();
                string[] coords = line.Split('|');
                // now add all the vertices
                for (var j = 0; j < coords.Length; j++)
                {
                    if (coords[j].StartsWith("KIND"))
                    {
                        var    start = coords[j].IndexOf('=') + 1;
                        string type  = coords[j].Substring(start);
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        string coord = coords[j].Substring(start);
                        // get start X
                        double VX = GetCoordinateX(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get start Y
                        double VY = GetCoordinateY(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get centre X
                        double CX = GetCoordinateX(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get centre Y
                        double CY = GetCoordinateY(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get start angle
                        double SA = GetDouble(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get end angle
                        double EA = GetDouble(coord.Trim(charsToTrim));
                        j++;
                        start = coords[j].IndexOf('=') + 1;
                        coord = coords[j].Substring(start);
                        // get radius
                        double R = GetNumberInMM(coord.Trim(charsToTrim));
                        if (type == "0")
                        {
                            // straight line
                            AddPoint(Math.Round(VX, Precision), Math.Round(VY, Precision));
                        }
                        else
                        {
                            // this is an arc so have to simulate arc with a number of line segments
                            // first normalise it so that the centre is at 0,0
                            // save the centre point
                            double XC = CX;
                            double YC = CY;

                            double X = VX - XC;
                            double Y = VY - YC;

                            // generate arc segments at 5° increments
                            if (EA < SA)
                            {
                                EA += 360;
                            }
                            // start point of arc
                            X = R * Math.Cos(Arc.Radians(SA));
                            Y = R * Math.Sin(Arc.Radians(SA));
                            // end point of arc
                            double X2        = R * Math.Cos(Arc.Radians(EA));
                            double Y2        = R * Math.Sin(Arc.Radians(EA));
                            bool   clockwise = true;
                            double l1        = Math.Sqrt((VX - (X + XC)) * (VX - (X + XC)) + (VY - (Y + YC)) * (VY - (Y + YC)));
                            double l2        = Math.Sqrt((VX - (X2 + XC)) * (VX - (X2 + XC)) + (VY - (Y2 + YC)) * (VY - (Y2 + YC)));
                            if (l1 < l2)
                            {
                                clockwise = false;
                            }

                            // need to determine if this is clockwise or anticlockwise as the
                            // start and end angles are back to front
                            if (!clockwise)
                            {
                                // anticlockwise
                                for (double angle = SA; angle < EA; angle += 5)
                                {
                                    double X1 = R * Math.Cos(Arc.Radians(angle));
                                    double Y1 = R * Math.Sin(Arc.Radians(angle));
                                    AddPoint(X + XC, Y + YC);
                                    X = X1;
                                    Y = Y1;
                                }

                                // do last segment
                                if (X != X2 || Y != Y2)
                                {
                                    AddPoint(X2 + XC, Y2 + YC);
                                }
                            }
                            else
                            {
                                // clockwise
                                // start point of arc
                                X = R * Math.Cos(Arc.Radians(EA));
                                Y = R * Math.Sin(Arc.Radians(EA));
                                // end point of arc
                                X2 = R * Math.Cos(Arc.Radians(SA));
                                Y2 = R * Math.Sin(Arc.Radians(SA));

                                for (double angle = EA; angle > SA; angle -= 5)
                                {
                                    double X1 = R * Math.Cos(Arc.Radians(angle));
                                    double Y1 = R * Math.Sin(Arc.Radians(angle));
                                    AddPoint(X + XC, Y + YC);
                                    X = X1;
                                    Y = Y1;
                                }

                                // do last segment
                                if (X != X2 || Y != Y2)
                                {
                                    AddPoint(X2 + XC, Y2 + YC);
                                }
                            }
                        }
                    }
                }
            }
Beispiel #6
0
            public override bool ProcessLine(byte[] record)
            {
                base.ProcessLine();
                using (MemoryStream ms = new MemoryStream(record))
                {
                    // Use the memory stream in a binary reader.
                    using (BinaryReader br = new BinaryReader(ms))
                    {
                        ms.Seek(0, SeekOrigin.Begin);
                        Layer   = (Layers)br.ReadByte(); // line offset 0
                        Locked  = br.ReadByte();         // line offset 1
                        Keepout = (int)br.ReadByte();    // line offset 2

                        ms.Seek(3, SeekOrigin.Begin);
                        Net     = br.ReadInt16();
                        Net    += 1;
                        NetName = $"\"{NetsL[Net].Name}\"";
                        ms.Seek(7, SeekOrigin.Begin);
                        Component   = br.ReadInt16();
                        InComponent = (Component != -1);
                        ms.Seek(13, SeekOrigin.Begin);
                        X1 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originX, Precision);
                        ms.Seek(17, SeekOrigin.Begin);
                        Y1 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originY, Precision);
                        ms.Seek(21, SeekOrigin.Begin);
                        X2 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originX, Precision);
                        ms.Seek(25, SeekOrigin.Begin);
                        Y2 = Math.Round(Bytes2mm(br.ReadBytes(4)) - originY, Precision);
                        ms.Seek(29, SeekOrigin.Begin);
                        Rotation = br.ReadDouble();
                        CheckMinMax(X1, Y1);
                        CheckMinMax(X2, Y2);
                    }
                    if (Keepout == 2)
                    {
                        Point2D p1 = new Point2D(X1, Y1);
                        Point2D p2 = new Point2D(X2, Y2);
                        Point2D c  = new Point2D(X1 + (X2 - X1) / 2, Y1 + (Y2 - Y1) / 2);
                        if (InComponent)
                        {
                            // need to factor in component's rotation
                            if (Component < ModulesL.Count)
                            {
                                try
                                {
                                    double rot = ModulesL[Component].Rotation;
                                    p1 = p1.Rotate(c, rot);
                                    p2 = p2.Rotate(c, rot);
                                }
                                catch (Exception Ex)
                                {
                                    CheckThreadAbort(Ex);
                                }
                            }
                        }
                        string layer = "";
                        if (Layer == Layers.Keepout_Layer)
                        {
                            layer = "*.Cu";
                        }
                        else
                        {
                            layer = Brd.GetLayer(Layer);
                        }
                        List <string> layers = Brd.GetLayers(layer);
                        foreach (var L in layers)
                        {
                            // generate a keepout
                            keepouts.Append(
                                $@"
    (zone(net 0)(net_name """")(layers {L})(tstamp 0)(hatch edge 0.508)
      (connect_pads(clearance 0.508))
      (min_thickness 0.254)
      (keepout(tracks not_allowed)(vias not_allowed)(copperpour not_allowed))
      (fill(arc_segments 32)(thermal_gap 0.508)(thermal_bridge_width 0.508))
      (polygon
        (pts
          (xy {p1.X} {-p1.Y})(xy {p2.X} {-p1.Y})(xy {p2.X} {-p2.Y})(xy {p1.X} {-p2.Y})
         )
      )
    )
");
                        }
                    }
                    else if (!InComponent) // keepouts not allowed in components (yet)
                    {
                        List <string> Layers = Brd.GetLayers(Brd.GetLayer(Layer));
                        foreach (var L in Layers)
                        {
                            fills.Append($"  (gr_poly (pts (xy {X1} {-(Y1)}) (xy {X1} {-(Y2)}) (xy {X2} {-(Y2)}) (xy {X2} {-(Y1)})) (layer {L}) (width 0))\n");
                        }
                    }
                    else
                    {
                        Fill Fill = new Fill(X1, Y1, X2, Y2, Brd.GetLayer(Layer), GetNetName(Net));
                        if (Component < ModulesL.Count && Component != -1)
                        {
                            ModulesL[Component].Fills.Add(Fill);
                        }
                    }
                    return(true);
                }
            }
Beispiel #7
0
            public override string ToString()
            {
                // for some reason the arc in version 5.99 needs start middle end
                // rather than start end angle like for fp_arc ... go figure
                // X1, Y1 = centre
                double Xs, Ys, Xm, Ym, Xe, Ye;

                Xs = Math.Round(X1 + Radius * Math.Cos(Radians(StartAngle)), Precision);
                Ys = Math.Round(Y1 + Radius * Math.Sin(Radians(StartAngle)), Precision);
                Xm = Math.Round(X1 + Radius * Math.Cos(Radians(StartAngle + (EndAngle - StartAngle) / 2)), Precision);
                Ym = Math.Round(Y1 + Radius * Math.Sin(Radians(StartAngle + (EndAngle - StartAngle) / 2)), Precision);
                Xe = Math.Round(X1 + Radius * Math.Cos(Radians(EndAngle)), Precision);
                Ye = Math.Round(Y1 + Radius * Math.Sin(Radians(EndAngle)), Precision);

                string netstr = (net == -1) ? "" : $"(net {net})";

                if (Brd.IsCopperLayer(Layer))
                {
                    return($"  (arc (start {Xs} {-Ys}) (mid {Xm} {-Ym}) (end {Xe} {-Ye}) (layer {Brd.GetLayer(Layer)}) {netstr} (width {Width}))\n");
                }
                else
                {
                    return($"  (gr_arc (start {Math.Round(X1, Precision)} {Math.Round(-Y1, Precision)}) (end {Math.Round(Xs, Precision)} {Math.Round(-Ys, Precision)}) (angle {Math.Round(-(EndAngle - StartAngle), Precision)}) (layer {Brd.GetLayer(Layer)}) (width {Width}))\n");
                }
            }
Beispiel #8
0
            public override bool ProcessLine(byte[] line)
            {
                double StartAngle, EndAngle, Radius, Width;
                Layers Layer;
                double X1, Y1;
                Int16  Component;
                Int16  net;

                base.ProcessLine();
                ArcStruct a = ByteArrayToStructure <ArcStruct>(line);

                Layer = (Layers)a.Layer;
                net   = a.net;
                net++;
                Component  = a.Component;
                X1         = Math.Round((double)a.X1 * 25.4 / 10000000 - originX, Precision);
                Y1         = Math.Round((double)a.Y1 * 25.4 / 10000000 - originY, Precision);
                Radius     = Math.Round((double)a.Radius * 25.4 / 10000000, Precision);
                StartAngle = a.StartAngle;
                EndAngle   = a.EndAngle;
                Width      = (double)a.Width * 25.4 / 10000000;

                bool   InComponent = Component != -1;
                double Angle;

                if (EndAngle < StartAngle)
                {
                    EndAngle += 360;
                }

                Angle = (EndAngle - StartAngle);
                double X     = X1 + Radius * Math.Cos(StartAngle * Math.PI / 180);
                double Y     = Y1 + Radius * Math.Sin(StartAngle * Math.PI / 180);
                string layer = Brd.GetLayer(Layer);

                if (!InComponent)
                {
                    if (net > 0 && Brd.IsCopperLayer(Layer))
                    {
                        if (!Globals.PcbnewVersion)
                        {
                            // arcs with nets on copper layers allowed in 5.99
                            Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Layer, Width, net);
                            ArcsL.Add(Arc);
                        }
                        else
                        {
                            //arcs.Append($"  (arc (start {Math.Round(X1, Precision)} {Math.Round(-Y1, Precision)}) (end {Math.Round(X, Precision)} {Math.Round(-Y, Precision)}) (angle {Math.Round(Angle, Precision)}) (layer {L}) (net {Net}) (width {Width}))\n");

                            // we have an arc/track on a copper layer and it has a net
                            // these aren't supported by KiCad yet so generate a curve out of track segments
                            // first normalise it so that the centre is at 0,0
                            // save the centre point
                            double XC = X1;
                            double YC = Y1;

                            X = X - XC;
                            Y = Y - YC;

                            double radius = Math.Sqrt(X * X + Y * Y);
                            // start angle in radians
                            double start_angle = Arc.Radians(StartAngle);
                            double end_angle   = Arc.Radians(EndAngle);
                            double X2          = Radius * Math.Cos(end_angle);
                            double Y2          = Radius * Math.Sin(end_angle);
                            X = Radius * Math.Cos(start_angle);
                            Y = Radius * Math.Sin(start_angle);

                            // generate arc segments at 5° increments
                            for (double angle = start_angle; angle < end_angle; angle += 2 * Math.PI / 72)
                            {
                                X1 = Radius * Math.Cos(angle);
                                Y1 = Radius * Math.Sin(angle);
                                Line Line = new Line(XC + X, YC + Y, XC + X1, YC + Y1, layer, Width, net);
                                LinesL.Add(Line);
                                X = X1;
                                Y = Y1;
                            }
                            // do last segment
                            if (X != X2 || Y != Y2)
                            {
                                Line Line = new Line(X + XC, Y + YC, X2 + XC, Y2 + YC, layer, Width, net);
                                LinesL.Add(Line);
                            }
                        }
                    }
                    else
                    {
                        // only add if not part of board outline
                        if ((layer != "Edge.Cuts") || !Brd.CheckExistingArc(X1, Y1, X, Y, Angle))
                        {
                            List <string> Layers = Brd.GetLayers(layer);
                            foreach (var L in Layers)
                            {
                                Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Brd.GetAltiumLayer(L), Width);
                                ArcsL.Add(Arc);
                            }
                        }
                    }
                }
                else
                {
                    Arc Arc = new Arc(X1, Y1, StartAngle, EndAngle, Radius, Layer, Width);
                    ModulesL[Component].Arcs.Add(Arc);
                }
                return(true);
            }
Beispiel #9
0
            public Module(string line)
            {
                string param;

                ObjectType = PCBObjectType.Module;
                Designator = "";
                Comment    = "";

                Name          = GetString(line, "|PATTERN=");
                ComponentKind = GetString(line, "|COMPONENTKIND=");
                if (Name.Contains("\\"))
                {
                    Name = Name.Replace("\\", "_"); // TODO check this out
                }
                if (Name.Contains("\""))
                {
                    Name = Name.Replace("\"", "_");
                }
                if ((param = GetString(line, "|X=").Trim(charsToTrim)) != "")
                {
                    X = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|Y=").Trim(charsToTrim)) != "")
                {
                    Y = GetCoordinateY(param);
                }
                Layer = "";
                if ((param = GetString(line, "|LAYER=")) != "")
                {
                    Layer = Brd.GetLayer(param);
                }
                DesignatorOn = true;
                if ((param = GetString(line, "|NAMEON=")) != "")
                {
                    DesignatorOn = param == "TRUE";
                }
                CommentOn = true;
                if ((param = GetString(line, "|COMMENTON=")) != "")
                {
                    CommentOn = param == "TRUE";
                }
                Locked = false;
                if ((param = GetString(line, "|LOCKED=")) != "")
                {
                    Locked = param == "TRUE";
                }
                PrimitiveLock = false;
                if ((param = GetString(line, "|PRIMITIVELOCK=")) != "")
                {
                    PrimitiveLock = param == "TRUE";
                }
                Rotation = 0;
                if ((param = GetString(line, "|ROTATION=").Trim(charsToTrim)) != "")
                {
                    Rotation = Convert.ToDouble(param);
                    if (Rotation == 360)
                    {
                        Rotation = 0;
                    }
                }
                if (Layer == "F.Cu" || Layer == "B.Cu")
                {
                    Attr = "smd";
                }
                else
                {
                    Attr = "";
                }
                if (ComponentKind == "1" || ComponentKind == "2" || ComponentKind == "4")
                {
                    Attr = "virtual";
                }
                Tedit  = "(tedit 0)";
                Tstamp = "(tstamp 0)";
                // create the object lists for this component
                Lines            = new ObjectList <Line>();
                Pads             = new ObjectList <Pad>();
                Strings          = new ObjectList <String>();
                ViasL            = new ObjectList <Via>();
                Arcs             = new ObjectList <Arc>();
                Fills            = new ObjectList <Fill>();
                Polygons         = new ObjectList <Polygon>();
                Regions          = new ObjectList <Region>();
                ComponentBodies  = new ObjectList <ComponentBody>();
                ShapeBasedModels = new ObjectList <ShapeBasedModel>();
                ID++; // update for next Module
            }
Beispiel #10
0
            public Dimension(string line)
            {
                string[] words = line.Split('|');
                string   param;

                ObjectType = PCBObjectType.Dimension;
                if ((param = GetString(line, "|X1=").Trim(charsToTrim)) != "")
                {
                    X1 = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|Y1=").Trim(charsToTrim)) != "")
                {
                    Y1 = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|X2=").Trim(charsToTrim)) != "")
                {
                    X2 = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|Y2=").Trim(charsToTrim)) != "")
                {
                    Y2 = GetCoordinateY(param);
                }

                if ((param = GetString(line, "|DIMENSIONKIND=")) != "")
                {
                    DIMENSIONKIND = Convert.ToInt16(param);
                }
                if ((param = GetString(line, "|DIMENSIONLAYER=")) != "")
                {
                    layer = Brd.GetLayer(param);
                }
                if ((param = GetString(line, "|LX=").Trim(charsToTrim)) != "")
                {
                    LX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|LY=").Trim(charsToTrim)) != "")
                {
                    LY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|HX=").Trim(charsToTrim)) != "")
                {
                    HX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|HY=").Trim(charsToTrim)) != "")
                {
                    HY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|REFERENCE0POINTX=").Trim(charsToTrim)) != "")
                {
                    REFERENCE0POINTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|REFERENCE0POINTY=").Trim(charsToTrim)) != "")
                {
                    REFERENCE0POINTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|REFERENCE1POINTX=").Trim(charsToTrim)) != "")
                {
                    REFERENCE1POINTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|REFERENCE1POINTY=").Trim(charsToTrim)) != "")
                {
                    REFERENCE1POINTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|TEXTPOSITION=")) != "")
                {
                    TextPosition = param;
                }

                if ((param = GetString(line, "|ANGLE=").Trim(charsToTrim)) != "")
                {
                    ANGLE = Math.Round(Convert.ToDouble(param), Precision);
                    if (ANGLE == 180 || ANGLE == 360)
                    {
                        ANGLE = 0;
                    }
                    if (ANGLE == 270)
                    {
                        ANGLE = 90;
                    }
                }
                if ((param = GetString(line, "|ARROWSIZE=").Trim(charsToTrim)) != "")
                {
                    ARROWSIZE = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|ARROWLINEWIDTH=").Trim(charsToTrim)) != "")
                {
                    ARROWLINEWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|ARROWLENGTH=").Trim(charsToTrim)) != "")
                {
                    ARROWLENGTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|LINEWIDTH=").Trim(charsToTrim)) != "")
                {
                    LINEWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "")
                {
                    TEXTHEIGHT = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTWIDTH=").Trim(charsToTrim)) != "")
                {
                    TEXTWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "")
                {
                    TEXTHEIGHT = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTX=").Trim(charsToTrim)) != "")
                {
                    TEXTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|TEXTY=").Trim(charsToTrim)) != "")
                {
                    TEXTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|TEXT1X=").Trim(charsToTrim)) != "")
                {
                    TEXT1X = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|TEXT1Y=").Trim(charsToTrim)) != "")
                {
                    TEXT1Y = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|TEXTPRECISION=").Trim(charsToTrim)) != "")
                {
                    TEXTPRECISION = Convert.ToInt32(param);
                }
                if ((param = GetString(line, "|TEXTFORMAT=").Trim(charsToTrim)) != "")
                {
                    TextFormat = Convert.ToInt32(param);
                }
                if ((param = GetString(line, "|TEXTDIMENSIONUNIT=").Trim(charsToTrim)) != "")
                {
                    DimensionUnit = param;
                }
                // translate to fit in worksheet
                Point2D R0     = new Point2D(REFERENCE0POINTX, REFERENCE0POINTY);
                Point2D R1     = new Point2D(REFERENCE1POINTX, REFERENCE1POINTY);
                Point2D centre = new Point2D(X1, Y1);

                // rotate the two reference points to make horizontal dimension
                R0 = R0.Rotate(centre, -ANGLE);
                R1 = R1.Rotate(centre, -ANGLE);
                Point2D end = new Point2D(R1.X, Y1);
                Point2D a1a = new Point2D(X1 + ARROWSIZE, Y1 + ARROWSIZE / 3);
                Point2D a1b = new Point2D(X1 + ARROWSIZE, Y1 - ARROWSIZE / 3);
                Point2D a2a = new Point2D(end.X - ARROWSIZE, end.Y + ARROWSIZE / 3);
                Point2D a2b = new Point2D(end.X - ARROWSIZE, end.Y - ARROWSIZE / 3);

                CheckMinMax(X1, Y1);
                CheckMinMax(end.X, end.Y);
                CheckMinMax(a1a.X, a1a.Y);
                CheckMinMax(a1b.X, a1b.Y);
                CheckMinMax(a2a.X, a2a.Y);
                CheckMinMax(a2b.X, a2b.Y);
            }
Beispiel #11
0
            public override string ToString()
            {
                if (DIMENSIONKIND != 1) // TODO fix this - filter out radial dimensions
                {
                    OutputError($"Unsupported Dimension kind ({DIMENSIONKIND}) at {X1},{Y1}");
                    return("");
                }
                // translate to fit in worksheet
                Point2D R0     = new Point2D(REFERENCE0POINTX, REFERENCE0POINTY);
                Point2D R1     = new Point2D(REFERENCE1POINTX, REFERENCE1POINTY);
                Point2D centre = new Point2D(X1, Y1);

                // rotate the two reference points to make horizontal dimension
                R0 = R0.Rotate(centre, -ANGLE);
                R1 = R1.Rotate(centre, -ANGLE);
                Point2D end = new Point2D(R1.X, Y1);

                // calculate the length of the crossbar
                length = R1.X - X1; // length in mm
                // calculate the end points of the arrow features
                Point2D a1a = new Point2D(X1 + ARROWSIZE, Y1 + ARROWSIZE / 3);
                Point2D a1b = new Point2D(X1 + ARROWSIZE, Y1 - ARROWSIZE / 3);
                Point2D a2a = new Point2D(end.X - ARROWSIZE, end.Y + ARROWSIZE / 3);
                Point2D a2b = new Point2D(end.X - ARROWSIZE, end.Y - ARROWSIZE / 3);

                if (length < 0)
                {
                    // there must be a better way to do this but hey ho
                    length = -length;
                    // calculate the end points of the arrow features
                    a1a = new Point2D(X1 - ARROWSIZE, Y1 + ARROWSIZE / 3);
                    a1b = new Point2D(X1 - ARROWSIZE, Y1 - ARROWSIZE / 3);
                    a2a = new Point2D(end.X + ARROWSIZE, end.Y + ARROWSIZE / 3);
                    a2b = new Point2D(end.X + ARROWSIZE, end.Y - ARROWSIZE / 3);
                }
                string units;
                int    UnitsIndex = 0;
                int    Ilength;
                int    Dlength;

                // convert length to string based on Units and precision
                switch (DimensionUnit)
                {
                case "Mils":
                    length     = length / 25.4 * 1000;
                    units      = "mil";
                    UnitsIndex = 1;
                    break;

                case "Millimeters":
                    units      = "mm";
                    UnitsIndex = 2;
                    break;

                case "Inches":
                    length     = length / 25.4;
                    units      = "in";
                    UnitsIndex = 0;
                    break;

                case "Centimeters":
                    length     = length / 10;
                    units      = "cm";
                    UnitsIndex = 2;     // no CM in Pcbnew (yet)
                    break;

                default:    // mm
                    units      = "mm";
                    UnitsIndex = 2;
                    break;
                }

                length = Math.Round(length, TEXTPRECISION);
                Int32 MP = Convert.ToInt32(Math.Pow(10, TEXTPRECISION));
                Int32 FP = Convert.ToInt32(length * Math.Pow(10, TEXTPRECISION));

                Ilength = FP / MP;
                Dlength = FP - Ilength * MP;
                string Decimal = Dlength.ToString("D" + TEXTPRECISION);

                if (TEXTPRECISION == 0)
                {
                    text = $"{Ilength}{units}";
                }
                else
                {
                    text = $"{Ilength}.{Decimal}{units}";
                }

                // rotate all the points back
                a1a = a1a.Rotate(centre, ANGLE);
                a1b = a1b.Rotate(centre, ANGLE);
                a2a = a2a.Rotate(centre, ANGLE);
                a2b = a2b.Rotate(centre, ANGLE);

                R0  = R0.Rotate(centre, ANGLE);
                R1  = R1.Rotate(centre, ANGLE);
                end = end.Rotate(centre, ANGLE);

                var    string1 = new StringBuilder("");
                var    Layers  = Brd.GetLayers(Brd.GetLayer(layer));
                string Justify = "";

                switch (TextPosition)
                {
                case "Auto":            break;     // just do centre

                case "Center":          break;     // just do centre

                case "Top":             break;     // just do centre

                case "Bottom":          break;     // just do centre

                case "Right":           Justify = "(justify right)"; break;

                case "Left":            Justify = "(justify left)";  break;

                case "InsideRight":     Justify = "(justify right)"; break;

                case "InsideLeft":      Justify = "(justify left)";  break;

                case "UniDirectional":  break;     // just do centre

                case "Manual":          break;     // just do centre
                }

                foreach (var L in Layers)
                {
                    string1.Append($@"
  (dimension 176 (width {LINEWIDTH}) (layer {L})
    (gr_text {text} (at {TEXT1X} {-TEXT1Y} {ANGLE}) (layer {L.ToString()})
        (effects (font (size {Math.Round(TEXTHEIGHT, Precision)} {Math.Round(TEXTHEIGHT, Precision)}) (thickness {Math.Round(LINEWIDTH, Precision)})) {Justify})
    )
    (format (units {UnitsIndex}) (units_format {1}) (precision {TEXTPRECISION}))
    (style  (thickness {TEXTWIDTH}) (arrow_length {ARROWLENGTH}) (text_position_mode {1}) (extension_height {1}) (extension_offset 0) keep_text_aligned )
    (feature1 (pts (xy {end.X} {-end.Y}) (xy {R1.X} {-R1.Y})  ))
    (feature2 (pts  (xy {X1} {-Y1}) (xy {R0.X} {-R0.Y})))
    (crossbar (pts (xy {X1} {-Y1}) (xy {end.X} {-end.Y})))
    (arrow1a  (pts (xy {X1} {-Y1}) (xy {a1a.X} {-a1a.Y})))
    (arrow1b  (pts (xy {X1} {-Y1}) (xy {a1b.X} {-a1b.Y})))
    (arrow2a  (pts (xy {end.X} {-end.Y}) (xy {a2a.X} {-a2a.Y})))
    (arrow2b  (pts (xy {end.X} {-end.Y}) (xy {a2b.X} {-a2b.Y})))
  )");
                }
                return(string1.ToString());
            }
Beispiel #12
0
            public override bool ProcessBinaryFile(byte[] data)
            {
                StartTimer();
                if (Binary_size == 0)
                {
                    return(false);
                }

                long   p = 0;
                Int32  len;
                string str = "";

                try
                {
                    using (MemoryStream ms = new MemoryStream(data))
                    {
                        long size = ms.Length;
                        if (size == 0)
                        {
                            return(true);
                        }
                        BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8);
                        while (p < size)
                        {
                            base.ProcessLine(); // keep count
                            byte record_type = br.ReadByte();
                            if (record_type != 5)
                            {
                                break;
                            }
                            len = br.ReadInt32();
                            byte[] bytes = br.ReadBytes(len); // 0xEC);  // read the number of bytes up to actual text
                            // map text structure to the bytes
                            Text text = ByteArrayToStructure <Text>(bytes);

                            Layers Layer        = (Layers)text.Layer;
                            Int16  Component    = text.Component;
                            bool   InComponent  = Component != -1;
                            double X            = Math.Round(ToMM(text.X) - originX, Precision);
                            double Y            = Math.Round(ToMM(text.Y) - originY, Precision);
                            double Height       = Math.Round(ToMM(text.Height), Precision);
                            double Width        = Math.Round(ToMM(text.Height), Precision);
                            double Rotation     = text.Rotation % 360; // altium seem to store 0 as 360 quite a lot!
                            bool   Mirror       = text.Mirror != 0;
                            double Thickness    = ToMM(text.Thickness);
                            bool   IsComment    = text.IsComment != 0;
                            bool   IsDesignator = text.IsDesignator != 0;
                            bool   TrueType     = text.TrueType != 0;
                            UInt32 TextLen      = br.ReadUInt32();
                            bool   Italic       = text.Italic != 0;
                            bool   Bold         = text.Bold != 0;

                            byte   strlen    = br.ReadByte();
                            byte[] textbytes = br.ReadBytes(strlen);
                            p = ms.Position; // now at end of record

                            str = Encoding.UTF8.GetString(textbytes, 0, strlen);
                            string layer = Brd.GetLayer(Layer);

                            str = ConvertSpecialStrings(str, Component, layer);
                            if (TrueType)
                            {
                                //string Font = text.FontName;
                                StringBuilder SB = new StringBuilder("");
                                unsafe
                                {
                                    for (int i = 0; i < 32; i++)
                                    {
                                        if (text.FontName[i] == 0)
                                        {
                                            break;
                                        }
                                        char c = (char)text.FontName[i];
                                        SB.Append(c);
                                    }
                                }
                                string     Font = SB.ToString();
                                TTFont     F;
                                FontFamily fontFamily = null;
                                try
                                {
                                    fontFamily = new FontFamily(Font);
                                    // check if font is on font list
                                    if ((F = FindFont(Font, Bold, Italic, Height)) == null)
                                    {
                                        // get metrics for font and bung it onto font list
                                        FontStyle Style           = ((Bold) ? FontStyle.Bold : 0) | ((Italic) ? FontStyle.Italic : 0);
                                        Font      font            = new Font(fontFamily, 100, Style, GraphicsUnit.Pixel);
                                        float     Ascent          = font.FontFamily.GetCellAscent(Style);
                                        float     Descent         = font.FontFamily.GetCellDescent(Style);
                                        float     EmHeight        = font.FontFamily.GetEmHeight(Style);
                                        float     TotalHeight     = Ascent + Descent;
                                        float     InternalLeading = TotalHeight - EmHeight;
                                        double    TTHeight        = (float)(Ascent - InternalLeading);
                                        F = new TTFont
                                        {
                                            FontName    = Font,
                                            Italic      = Italic,
                                            Bold        = Bold,
                                            TotalHeight = TotalHeight,
                                            TTHeight    = TTHeight,
                                            Height      = Height
                                        };
                                        Height     = Height / F.TotalHeight * F.TTHeight;
                                        Height     = Height - Height / 5;
                                        F.TTHeight = Height;
                                        Size CharWidth = TextRenderer.MeasureText("A", font);
                                        F.CharWidth = Height * ((float)CharWidth.Height / (float)CharWidth.Width);
                                        Fonts.Add(F);
                                    }
                                    Height    = F.TTHeight;
                                    Thickness = Height / (Bold ? 5 : 10);
                                    Width     = F.CharWidth;
                                }
                                catch (ArgumentException)
                                {
                                    OutputError($"Font {Font} does not exist on this computer");
                                    // couldn't find font so estimate size
                                    Height = Height / 2;
                                    Width  = Height;
                                }
                            }

                            str = str.Replace("\r", "");
                            str = str.Replace("\n", "\\n");
                            if (!InComponent)
                            {
                                double Angle = (90 - Rotation) * Math.PI / 180;
                                double X1    = Height / 2 * Math.Cos(Angle);
                                double Y1    = Height / 2 * Math.Sin(Angle);

                                List <string> Layers = Brd.GetLayers(layer);
                                foreach (var L in Layers)
                                {
                                    string It = Italic ? "italic" : "";
                                    texts.Append($"  (gr_text \"{ToLiteral(str)}\" (at {Math.Round(X - X1, Precision)} {-Math.Round(Y + Y1, Precision)} {Math.Round(Rotation, Precision)})  (layer {L}) (effects (font (size {Height} {Width}) (thickness {Thickness}) {It}) (justify left {(Mirror ? "mirror" : "")})))\n");
                                }
                            }
                            else
                            {
                                Module Mod  = ModulesL[Component];
                                string Hide = "";
                                string type = "";
                                if (IsDesignator)
                                {
                                    type = "reference";
                                    Hide = Mod.DesignatorOn ? "" : "hide";
                                    if (Brd.DesignatorDisplayMode && str.Contains("_"))
                                    {
                                        // This is a virtual designator
                                        // Pcbnew doesn't have anything like this so
                                        // set the designator onto the Dwgs.User layer
                                        // and put a copy minus the channel designator on the
                                        // top/bottom overlay layer
                                        //    str = str.Substring(0, str.IndexOf('_'));
                                    }
                                    Mod.Designator = str;
                                }
                                else if (IsComment)
                                {
                                    type = "value";
                                    Hide = Mod.CommentOn ? "" : "hide";
                                    if (layer == "F.Cu")
                                    {
                                        layer = "F.Fab";
                                    }
                                    else
                                    if (layer == "B.Cu")
                                    {
                                        layer = "B.Fab";
                                    }

                                    /*if (Brd.DesignatorDisplayMode)
                                     * {
                                     *  // should get the seperator from the project file (.PrjPCB)
                                     *  // under ChannelRoomLevelSeperator
                                     *  // can't find it in board data assume it's '_'
                                     *  str = str.Substring(0, str.IndexOf('_'));
                                     * }*/
                                    Mod.Comment = ToLiteral(str);
                                }
                                else
                                {
                                    type = "user";
                                    if (str == Mod.Comment)
                                    {
                                        str = "%V";
                                    }
                                    if (str == Mod.Designator)
                                    {
                                        str = "%R";
                                    }
                                }

                                if (Hide == "")
                                {
                                    GetBoundingBox(str, X, Y, Rotation, Height, Width);
                                }

                                if (Brd.DesignatorDisplayMode && str.Contains("_"))
                                {
                                    // put designator on Dwgs.User and virtual designator on silkscreen
                                    String S1 = new String(type, str, X, Y, Rotation, "Dwgs.User", Height, Width, Thickness, Hide, Mirror, Italic);
                                    ModulesL[Component].Strings.Add(S1);
                                    str = str.Substring(0, str.IndexOf('_'));
                                    String S2 = new String("user", str, X, Y, Rotation, layer, Height, Width, Thickness, Hide, Mirror, Italic);
                                    ModulesL[Component].Strings.Add(S2);
                                }
                                else
                                {
                                    String String = new String(type, str, X, Y, Rotation, layer, Height, Width, Thickness, Hide, Mirror, Italic);
                                    ModulesL[Component].Strings.Add(String);
                                }
                            }
                        }
                    }
                }
                catch (Exception Ex)
                {
                    CheckThreadAbort(Ex);
                }

                return(true);
            }
Beispiel #13
0
            public override bool ProcessLine(byte[] record)
            {
                Layers Layer;
                Int16  Component;
                bool   InComponent;

                base.ProcessLine();

                using (MemoryStream ms = new MemoryStream(record))
                {
                    // Use the memory stream in a binary reader.
                    using (BinaryReader br = new BinaryReader(ms))
                    {
                        try
                        {
                            ms.Seek(0, SeekOrigin.Begin);
                            Layer = (Layers)br.ReadByte();
                            ms.Seek(1, SeekOrigin.Begin);
                            short Flags = (short)br.ReadInt16();
                            ms.Seek(3, SeekOrigin.Begin);
                            int net = (int)br.ReadInt16() + 1;
                            ms.Seek(7, SeekOrigin.Begin);
                            Component   = br.ReadInt16();
                            InComponent = Component != -1;
                            ms.Seek(0x12, SeekOrigin.Begin);
                            int strlen = br.ReadInt32();
                            ms.Seek(0x16, SeekOrigin.Begin);
                            byte[] bytes = br.ReadBytes(strlen);
                            string str   = ConvertToString(bytes);
                            ms.Seek(0x16 + strlen, SeekOrigin.Begin);
                            Int32  DataLen = br.ReadInt32();
                            string l       = Brd.GetLayer((Layers)Layer);
                            Region r       = new Region(l, net, Flags, str);
                            if (r.SubPolyIndex > 0)
                            {
                                // Rejected region
                                return(true);
                            }
                            while (DataLen-- > 0)
                            {
                                double X = Math.Round(ToMM(br.ReadDouble()) - originX, Precision);
                                double Y = Math.Round(ToMM(br.ReadDouble()) - originY, Precision);
                                r.AddPoint(X, Y);
                            }

                            if (!InComponent)
                            {
                                RegionsL.Add(r);
                            }
                            else
                            {
                                if (!r.Keepout && !r.PolygonCutout)
                                {
                                    ModulesL[Component].Regions.Add(r);
                                }
                                else
                                {
                                    // until keepouts are allowed in components
                                    // just add as a board region
                                    RegionsL.Add(r);
                                }
                            }
                        }
                        catch (Exception Ex)
                        {
                            CheckThreadAbort(Ex);
                        }
                    }
                }

                return(true);
            }
Beispiel #14
0
            public Dimension(string line)
            {
                string param;

                if ((param = GetString(line, "|X1=").Trim(charsToTrim)) != "")
                {
                    X1 = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|Y1=").Trim(charsToTrim)) != "")
                {
                    Y1 = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|X2=").Trim(charsToTrim)) != "")
                {
                    X2 = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|Y2=").Trim(charsToTrim)) != "")
                {
                    Y2 = GetCoordinateY(param);
                }

                if ((param = GetString(line, "|DIMENSIONKIND=")) != "")
                {
                    DIMENSIONKIND = Convert.ToInt16(param);
                }
                if ((param = GetString(line, "|DIMENSIONLAYER=")) != "")
                {
                    layer = Brd.GetLayer(param);
                }
                if ((param = GetString(line, "|LX=").Trim(charsToTrim)) != "")
                {
                    LX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|LY=").Trim(charsToTrim)) != "")
                {
                    LY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|HX=").Trim(charsToTrim)) != "")
                {
                    HX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|HY=").Trim(charsToTrim)) != "")
                {
                    HY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|REFERENCE0POINTX=").Trim(charsToTrim)) != "")
                {
                    REFERENCE0POINTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|REFERENCE0POINTY=").Trim(charsToTrim)) != "")
                {
                    REFERENCE0POINTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|REFERENCE1POINTX=").Trim(charsToTrim)) != "")
                {
                    REFERENCE1POINTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|REFERENCE1POINTY=").Trim(charsToTrim)) != "")
                {
                    REFERENCE1POINTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|ANGLE=").Trim(charsToTrim)) != "")
                {
                    ANGLE = Math.Round(Convert.ToDouble(param), Precision);
                    if (ANGLE == 180 || ANGLE == 360)
                    {
                        ANGLE = 0;
                    }
                    if (ANGLE == 270)
                    {
                        ANGLE = 90;
                    }
                }
                if ((param = GetString(line, "|ARROWSIZE=").Trim(charsToTrim)) != "")
                {
                    ARROWSIZE = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|ARROWLINEWIDTH=").Trim(charsToTrim)) != "")
                {
                    ARROWLINEWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|ARROWLENGTH=").Trim(charsToTrim)) != "")
                {
                    ARROWLENGTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|LINEWIDTH=").Trim(charsToTrim)) != "")
                {
                    LINEWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "")
                {
                    TEXTHEIGHT = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTWIDTH=").Trim(charsToTrim)) != "")
                {
                    TEXTWIDTH = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTHEIGHT=").Trim(charsToTrim)) != "")
                {
                    TEXTHEIGHT = GetNumberInMM(param);
                }
                if ((param = GetString(line, "|TEXTX=").Trim(charsToTrim)) != "")
                {
                    TEXTX = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|TEXTY=").Trim(charsToTrim)) != "")
                {
                    TEXTY = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|TEXT1X=").Trim(charsToTrim)) != "")
                {
                    TEXT1X = GetCoordinateX(param);
                }
                if ((param = GetString(line, "|TEXT1Y=").Trim(charsToTrim)) != "")
                {
                    TEXT1Y = GetCoordinateY(param);
                }
                if ((param = GetString(line, "|TEXTPRECISION=").Trim(charsToTrim)) != "")
                {
                    TEXTPRECISION = Convert.ToInt32(param);
                }
                if ((param = GetString(line, "|TEXTDIMENSIONUNIT=").Trim(charsToTrim)) != "")
                {
                    DimensionUnit = param;
                }
            }
Beispiel #15
0
            public override bool ProcessLine(byte[] line)
            {
                double X1, Y1, X2, Y2, width;
                int    net;
                Layers layer;
                bool   InComponent = false;
                Int16  component   = 0;

                base.ProcessLine();
                net = B2UInt16(line, 3 + 5);
                if (net == 0x0000FFFF)
                {
                    net = 0;
                }
                else
                {
                    net++;
                }
                component   = B2Int16(line, 7 + 5);
                InComponent = (component != -1);
                X1          = Math.Round(ToMM(line, 13 + 5) - originX, Precision);
                Y1          = Math.Round(ToMM(line, 17 + 5) - originY, Precision);
                X2          = Math.Round(ToMM(line, 21 + 5) - originX, Precision);
                Y2          = Math.Round(ToMM(line, 25 + 5) - originY, Precision);

                CheckMinMax(X1 + originX, Y1 + originY);
                CheckMinMax(X2 + originX, Y2 + originY);
                width = Math.Round(ToMM(line, 29 + 5), Precision);

                layer = (Layers)line[5];
                string Layer           = Brd.GetLayer(layer);
                int    ComponentNumber = 0;

                if (InComponent)
                {
                    // belongs to a component definition
                    ComponentNumber = component;
                }
                // check for and reject very short tracks
                if (Length(X1, Y1, X2, Y2) <= 0.001)
                {
                    OutputError($"Zero length track rejected at X1={X1} Y1={-Y1} X2={X2} y2={-Y2} ");
                    return(true);
                }
                if (!InComponent)
                {
                    if (net == 0)
                    {
                        if (!Brd.OnInnerLayer(layer))
                        {
                            if ((Layer != "Edge.Cuts") || !Brd.CheckExistingLine(X1, -Y1, X2, -Y2))
                            {
                                List <string> Layers = Brd.GetLayers(Layer);
                                foreach (var L in Layers)
                                {
                                    Line Line = new Line(X1, Y1, X2, Y2, L, width, net);
                                    LinesL.Add(Line);
                                }
                            }
                        }
                    }
                    else
                    {
                        Line Line = new Line(X1, Y1, X2, Y2, Brd.GetLayer(layer), width, net);
                        LinesL.Add(Line);
                        //tracks.Append($"  (segment (start {X1} {-Y1}) (end {X2} {-Y2}) (width {width}) (layer {Layer}) (net {net}))\n");
                        //track_count++;
                    }
                }
                else
                {
                    Line Line = new Line(X1, Y1, X2, Y2, Brd.GetLayer(layer), width);
                    ModulesL[ComponentNumber].Lines.Add(Line);
                }
                return(true);
            }
Beispiel #16
0
            public override bool ProcessBinaryFile(byte[] data)
            {
                bool       GenerateTxtFile = true; // set to true to generate text version of the file
                FileStream TextFile        = null;

                StartTimer();
                if (Binary_size == 0)
                {
                    return(false);
                }

                if (GenerateTxtFile)
                {
                    if (ExtractFiles)
                    {
                        TextFile = File.Open("Data.txt", FileMode.OpenOrCreate);
                    }
                }
                try
                {
                    using (MemoryStream ms = new MemoryStream(data))
                    {
                        UInt32 pos  = 0;
                        uint   size = (uint)ms.Length;

                        BinaryReader br = new BinaryReader(ms, System.Text.Encoding.UTF8);
                        ms.Seek(pos, SeekOrigin.Begin);
                        List <UInt32> Starts = new List <UInt32>();
                        // look for record starts
                        {
                            Stopwatch timer = new Stopwatch();
                            timer.Start();
                            // signature is
                            // byte 02
                            // int32 length
                            // byte strlen = length - 1
                            // string strlen ascci chars
                            // bytes 01 00 00 00
                            while (pos < size)
                            {
                                ms.Seek(pos, SeekOrigin.Begin);
                                byte recordtype = br.ReadByte(); // should be 2
                                if (recordtype == 2)
                                {
                                    // possible start
                                    UInt32 nextnamelength = br.ReadUInt32();
                                    if (nextnamelength < 256)
                                    {
                                        uint l = br.ReadByte(); // string length
                                        if (l == nextnamelength - 1)
                                        {
                                            // everything ok so far
                                            // now check bytes in string are ASCII
                                            bool found = true;
                                            for (int i = 0; i < l; i++)
                                            {
                                                byte c = br.ReadByte();
                                                if (c < 0x20 || c > 0x7F)
                                                {
                                                    found = false;
                                                }
                                            }
                                            if (br.ReadByte() != 1)
                                            {
                                                found = false;
                                            }
                                            if (br.ReadByte() != 0)
                                            {
                                                found = false;
                                            }
                                            if (br.ReadByte() != 0)
                                            {
                                                found = false;
                                            }
                                            if (br.ReadByte() != 0)
                                            {
                                                found = false;
                                            }
                                            if (br.ReadByte() != 0)
                                            {
                                                found = false;
                                            }
                                            if (found)
                                            {
                                                // OutputString($"Found header at {pos:x08}");
                                                Starts.Add(pos);
                                            }
                                        }
                                    }
                                }
                                pos = pos + 1;
                            }
                        }
                        pos = 0;
                        int    index = -1;
                        Int16  Component;
                        byte[] r = br.ReadBytes(2);

                        try
                        {
                            UInt32 Longest = 0;
                            UInt32 len;
                            // find the length of the logest pad record
                            foreach (var p in Starts)
                            {
                                index++;
                                if (index < Starts.Count - 1)
                                {
                                    len = Starts[index + 1] - Starts[index];
                                }
                                else
                                {
                                    len = size - Starts[index];
                                }
                                if (len > Longest)
                                {
                                    Longest = len;
                                }
                            }
                            index = -1;
                            if (GenerateTxtFile && ExtractFiles)
                            {
                                AddText(TextFile, $"Altium Version {VersionString}\n");
                                // generate headers for .txt file
                                string Header1 = "Pos                 ";
                                for (int i = 0; i < Longest; i++)
                                {
                                    Header1 += $"{(i / 100),-3:D2}";
                                }
                                string Header2 = "                    ";
                                for (int i = 0; i < Longest; i++)
                                {
                                    Header2 += $"{(i % 100),-3:D2}";
                                }
                                string Header3 = "--------------------";
                                for (int i = 0; i < Longest; i++)
                                {
                                    Header3 += $"---";
                                }
                                if (ExtractFiles)
                                {
                                    AddText(TextFile, Header1 + "\n");
                                    AddText(TextFile, Header2 + "\n");
                                    AddText(TextFile, Header3 + "\n");
                                }
                            }
                            foreach (var p in Starts)
                            {
                                pos = p;
                                //OutputString($"Processing pad record at {pos:x08}");
                                index++;
                                base.ProcessLine();
                                ms.Seek(p, SeekOrigin.Begin);
                                byte   recordtype = br.ReadByte(); // should be 2
                                UInt32 next       = br.ReadUInt32();
                                uint   l          = br.ReadByte(); // string length
                                                                   //pos =  (uint)ms.Position;
                                string name;
                                if (l != 0)
                                {
                                    name = new string(br.ReadChars((int)l));
                                }
                                else
                                {
                                    name = "";
                                }
                                pos = (uint)ms.Position;
                                // find out how many bytes to read
                                if (index < Starts.Count - 1)
                                {
                                    len = Starts[index + 1] - Starts[index];
                                }
                                else
                                {
                                    len = size - Starts[index];
                                }

                                // we are now pointing to the pad record
                                //
                                Layers Layer;
                                byte   shape;
                                bool   plated;
                                double X, Y, XSize, YSize, HoleSize; //, MIDXSize, MIDYSize, BottomXSize, BottomYSize;
                                double Rotation = 0;
                                double RRatio   = 0;
                                Int16  Net;
                                Int16  JumperID;
                                byte[] bytes = br.ReadBytes((int)len - 6); // get record after header stuff

                                if (GenerateTxtFile)
                                {
                                    if (p == 0)
                                    {
                                        r = bytes; // get reference bytes
                                    }
                                    StringBuilder text         = new StringBuilder("");
                                    int           count        = 0;
                                    int           CompareLimit = Math.Min(r.Length, bytes.Length);
                                    foreach (var c in bytes)
                                    {
                                        if (count < CompareLimit && r[count] != bytes[count])
                                        {
                                            text.Append($"|{c:X2}");
                                        }
                                        else
                                        {
                                            text.Append($" {c:X2}");
                                        }
                                        count++;
                                    }
                                    if (ExtractFiles)
                                    {
                                        AddText(TextFile, $"{pos:X8} " + $"{len - name.Length,4} {name,4} {text.ToString()}\n");
                                    }
                                }
                                PadStruct pad = ByteArrayToStructure <PadStruct>(bytes);
                                ms.Seek(pos + pad.Offset, SeekOrigin.Begin);
                                int LayersSize = System.Runtime.InteropServices.Marshal.SizeOf(typeof(PadLayers));

                                byte[]    layerbytes = br.ReadBytes(LayersSize); // get layers data
                                PadLayers PadLayers  = ByteArrayToStructure <PadLayers>(layerbytes);
                                Layer = (Layers)pad.Layer;
                                Net   = pad.Net;
                                Net++;
                                string n = NetsL[Net].Name;
                                Component = pad.Component;
                                if (Component != -1 && Component != 0)
                                {
                                    X = 0;
                                }
                                X        = ToMM(pad.X) - originX;
                                Y        = ToMM(pad.Y) - originY;
                                XSize    = ToMM(pad.XSize);
                                YSize    = ToMM(pad.YSize);
                                HoleSize = ToMM(pad.HoleSize);
                                unsafe
                                {
                                    shape = pad.TopShape;
                                    if (len > 160 && shape == 1) // TODO this can't be right
                                    {
                                        shape  = PadLayers.PadShapes[0];
                                        RRatio = (double)PadLayers.RRatios[0] / 200;
                                    }
                                    else
                                    {
                                        RRatio = 0;
                                    }
                                }
                                if (shape > 5)
                                {
                                    shape = 5;
                                }
                                string[] shapes = { "circle", "circle", "rect", "octagonal", "oval", "roundrect" };
                                if (shapes[shape] == "circle" && XSize != YSize)
                                {
                                    shape = 4; // oval pad
                                }
                                Rotation = pad.Rotation;
                                plated   = pad.Plated != 0;
                                JumperID = pad.JumperID;
                                bool InComponent = Component != -1;

                                string type;
                                if (Layer == Layers.Multi_Layer)
                                {
                                    if (plated)
                                    {
                                        type = "thru_hole";
                                    }
                                    else
                                    {
                                        type = "np_thru_hole";
                                        //    name = "\"\"";
                                    }
                                    if (HoleSize < 0.01)
                                    {
                                        OutputError($"Zero size hole through hole pad at {X} {Y}");
                                    }
                                }
                                else
                                {
                                    type = "smd";
                                }
                                string layer = Brd.GetLayer(Layer);
                                if (!Brd.IsCopperLayer(Layer))
                                {
                                    OutputError($"Pad on non copper layer = {Layer} at {X} {-Y}");
                                    // TODO generate circular polygon instead
                                    continue;
                                }
                                if (layer == "Margin") // TODO sort this keepout layer malarky
                                {
                                    layer = "Dwgs.User";
                                }
                                if (type == "smd")
                                {
                                    layer += layer == "F.Cu" ? " F.Mask F.Paste" : (layer == "B.Cu") ? " B.Mask B.Paste" : "";
                                }
                                else
                                {
                                    layer += " *.Mask";
                                }

                                if (XSize < HoleSize | YSize < HoleSize)
                                {
                                    XSize = YSize = HoleSize;
                                }

                                Pad Pad = new Pad(name, type, shapes[shape], X, Y, Rotation, XSize, YSize, HoleSize, layer, Net, RRatio)
                                {
                                    Component = Component
                                };
                                if (pad.UsePasteMaskRules == 1)
                                {
                                    Pad.PasteMaskExpansion = GetRuleValue(Pad, "PasteMaskExpansion", "PasteMaskExpansion");
                                }
                                else
                                {
                                    Pad.PasteMaskExpansion = ToMM(pad.PasteMaskExpansion);
                                }
                                if (pad.UseSolderMaskRules == 1)
                                {
                                    Pad.SolderMaskExpansion = GetRuleValue(Pad, "SolderMaskExpansion", "SolderMaskExpansion");
                                }
                                else
                                {
                                    Pad.SolderMaskExpansion = ToMM(pad.SolderMaskExpansion);
                                }


                                if (!InComponent)
                                {
                                    PadsL.Add(Pad);
                                    // free pads not allowed (at present) in PcbNew so generate a single pad module
                                    Module M = new Module($"FreePad{ModulesL.Count}", X, Y, XSize, YSize, Pad);
                                    ModulesL.Add(M);
                                }
                                else
                                {
                                    try
                                    {
                                        ModulesL[Component].Pads.Add(Pad);
                                    }
                                    catch (Exception Ex)
                                    {
                                        CheckThreadAbort(Ex, $"At position {pos} in Pads file");
                                    }
                                }
                            }
                        }
                        catch (Exception Ex)
                        {
                            CheckThreadAbort(Ex);
                        }
                        if (GenerateTxtFile && TextFile != null)
                        {
                            TextFile.Close();
                        }
                    }
                }
                catch (Exception Ex)
                {
                    CheckThreadAbort(Ex);
                }

                return(true);
            }