Example #1
0
        private void ReadPrimitives(BinaryReader reader)
        {
            BeginContext("ReadPrimitives");

            Root        = new SchPrimitive();
            Root.Record = -1;

            var primitives = new List <SchPrimitive>();

            while (reader.BaseStream.Position < reader.BaseStream.Length)
            {
                var primitiveStartPosition = reader.BaseStream.Position;
                var primitive = ReadRecord(reader,
                                           size => ReadAsciiRecord(reader, size),
                                           size => ReadPinRecord(reader, size));

                primitive.SetRawData(ExtractStreamData(reader, primitiveStartPosition, reader.BaseStream.Position));

                /*
                 * if (Sheet == null)
                 * {
                 *  // First primitive read must be the board Record31
                 *  AssertValue(nameof(primitive), primitive.GetType().Name, typeof(SheetRecord).Name);
                 *  Sheet = (SheetRecord)primitive;
                 * }
                 */
                primitives.Add(primitive);
            }

            AssignOwners(primitives);

            EndContext();
        }
Example #2
0
        /// <summary>
        /// Instantiates a record according to its record type number.
        /// </summary>
        /// <param name="recordType">Integer representing the record type.</param>
        /// <returns>A new empty instance of a record primitive.</returns>
        private SchPrimitive CreateRecord(int recordType)
        {
            SchPrimitive record;

            switch (recordType)
            {
            case 1:
                record = new SchComponent();
                break;

            case 2:
                record = new PinRecord();
                break;

            case 3:
                record = new SymbolRecord();
                break;

            case 4:
                record = new TextStringRecord();
                break;

            case 5:
                record = new BezierRecord();
                break;

            case 6:
                record = new PolylineRecord();
                break;

            case 7:
                record = new PolygonRecord();
                break;

            case 8:
                record = new EllipseRecord();
                break;

            case 9:
                record = new PieChartRecord();
                break;

            case 10:
                record = new RoundedRectangleRecord();
                break;

            case 11:
                record = new EllipticalArcRecord();
                break;

            case 12:
                record = new ArcRecord();
                break;

            case 13:
                record = new LineRecord();
                break;

            case 14:
                record = new RectangleRecord();
                break;

            case 28:
            case 209:
                record = new TextFrameRecord();
                break;

            case 30:
                record = new ImageRecord();
                break;

            case 34:
                record = new Record34();
                break;

            case 41:
                record = new Record41();
                break;

            case 44:
                record = new Record44();
                break;

            case 45:
                record = new Record45();
                break;

            case 46:
                record = new Record46();
                break;

            case 48:
                record = new Record48();
                break;

            default:
                EmitWarning($"Record {recordType} not supported");
                record = new SchPrimitive();
                break;
            }

            return(record);
        }
Example #3
0
 protected static void WritePrimitive(BinaryWriter writer, SchPrimitive primitive, bool pinAsBinary,
                                      int ownerIndex, ref int index, ref int pinIndex,
                                      Dictionary <int, (int x, int y, int length)> pinsFrac,
Example #4
0
        /// <summary>
        /// Converts the components and their schematic symbols from a BxlSharp document
        /// to the equivalent AltiumSharp schematic library.
        /// <remarks>
        /// This ignores the components' footprints.
        /// </remarks>
        /// </summary>
        /// <param name="document">BxlSharp document to have their schematic library data converted</param>
        /// <param name="hideAllParameters">
        /// Many BXL documents have by default <c>RefDes</c> and <c>Value</c> attributes marked as
        /// being visible. If this argument is <c>true</c> then the visibility is ignored when
        /// creating the respective AltiumSharp component schematic parameters.</param>
        /// <param name="overrideRectangleLineWidth">
        /// Optional value to be used when creating the rectangles in the document, instead of the
        /// values provided in the BxlSharp document.
        /// </param>
        /// <returns></returns>
        public static SchLib ConvertSymbols(BxlDocument document, bool hideAllParameters = false,
                                            LineWidth?overrideRectangleLineWidth         = null, bool convertOverlines = true)
        {
            var schlib = new SchLib();

            foreach (var component in document.Components)
            {
                var schComponent = new SchComponent
                {
                    LibReference = component.Name,
                    Designator   = { Text = $"{component.RefDesPrefix}?" }
                };

                // Read the general parameters for the component
                foreach (var libitem in component.Data)
                {
                    SchPrimitive schPrimitive = null;
                    switch (libitem)
                    {
                    case LibAttribute libAttribute:
                        schPrimitive = new SchParameter
                        {
                            Location      = ConvertPoint(libAttribute.Origin),
                            Name          = libAttribute.Name,
                            Text          = libAttribute.Text,
                            FontId        = GetFontId(schlib, document, libAttribute.TextStyle),
                            Justification = ConvertJustification(libAttribute.Justify),
                            Orientation   = ConvertRotatation(libAttribute.Rotate),
                            IsMirrored    = libAttribute.IsFlipped,
                            IsHidden      = true,
                        };
                        if (libAttribute.Name?.Equals("DESCRIPTION",
                                                      StringComparison.InvariantCultureIgnoreCase) == true)
                        {
                            schComponent.ComponentDescription = libAttribute.Text;
                        }
                        break;

                    case LibWizard libWizard:
                        schPrimitive = new SchParameter
                        {
                            Location = ConvertPoint(libWizard.Origin),
                            Name     = libWizard.VarName,
                            Text     = libWizard.VarData
                        };
                        break;
                    }

                    if (schPrimitive != null)
                    {
                        schComponent.Add(schPrimitive);
                    }
                }

                // needed for fetching some parameter values
                var footprint = document.GetFootprint(component.PatternName);

                // each component has a set of schematic symbols equivalent to AD display modes and part numbers,
                // so we group them by part number and then iterate over each part's display modes
                var attachedSymbolsByPartNum =
                    component.AttachedSymbols.Where(s => !string.IsNullOrEmpty(s.SymbolName))
                    .GroupBy(s => s.PartNum);

                foreach (var group in attachedSymbolsByPartNum)
                {
                    var partNum = group.Key;
                    if (partNum > schComponent.PartCount)
                    {
                        schComponent.AddPart();
                    }

                    var displayMode = 0;
                    foreach (var attachedSymbol in group)
                    {
                        var symbol = document.GetSymbol(attachedSymbol.SymbolName);
                        if (symbol == null)
                        {
                            continue;
                        }

                        if (displayMode >= schComponent.DisplayModeCount)
                        {
                            schComponent.AddDisplayMode();
                        }

                        var ignored = new HashSet <LibItem>();

                        // detect rectangles first so the are drawn in the background
                        for (int j = 0; j < symbol.Data.Count; ++j)
                        {
                            if (DetectRectangle(symbol.Data, j, out var rectangle))
                            {
                                ignored.Add(symbol.Data[j]);
                                ignored.Add(symbol.Data[j + 1]);
                                ignored.Add(symbol.Data[j + 2]);
                                ignored.Add(symbol.Data[j + 3]);
                                j += 3;

                                rectangle.LineWidth = overrideRectangleLineWidth ?? rectangle.LineWidth;
                                schComponent.Add(rectangle);
                            }
                        }

                        foreach (var libitem in symbol.Data.Where(li => !ignored.Contains(li)))
                        {
                            SchPrimitive schPrimitive = null;
                            switch (libitem)
                            {
                            case LibLine libLine:
                                schPrimitive = new SchLine
                                {
                                    Location  = ConvertPoint(libLine.Origin),
                                    Corner    = ConvertPoint(libLine.EndPoint),
                                    LineWidth = ConvertWidth(libLine.Width)
                                };
                                break;

                            case LibPoly libPoly:
                                schPrimitive = new SchPolyline
                                {
                                    Vertices  = ConvertPoints(libPoly.Points),
                                    LineWidth = ConvertWidth(libPoly.Width)
                                };
                                break;

                            case LibArc libArc:
                                schPrimitive = new SchArc
                                {
                                    Location   = ConvertPoint(libArc.Origin),
                                    Radius     = Coord.FromMils(libArc.Radius),
                                    StartAngle = libArc.StartAngle,
                                    EndAngle   = libArc.StartAngle + libArc.SweepAngle,
                                    LineWidth  = ConvertWidth(libArc.Width)
                                };
                                break;

                            case LibText libText:
                                schPrimitive = new SchLabel
                                {
                                    Location      = ConvertPoint(libText.Origin),
                                    Text          = libText.Text,
                                    FontId        = GetFontId(schlib, document, libText.TextStyle),
                                    Justification = ConvertJustification(libText.Justify),
                                    Orientation   = ConvertRotatation(libText.Rotate),
                                    IsMirrored    = libText.IsFlipped,
                                    IsHidden      = !libText.IsVisible,
                                };
                                break;

                            case LibPin libPin:
                                schPrimitive = new SchPin
                                {
                                    Location          = ConvertPoint(libPin.Origin),
                                    Designator        = libPin.Designator.Text,
                                    Name              = ConvertPinName(libPin.Name.Text, convertOverlines),
                                    NameVisible       = libPin.Name.IsVisible,
                                    Orientation       = ConvertRotatation(libPin.Rotate),
                                    DesignatorVisible = libPin.Designator.IsVisible,
                                    PinLength         = Coord.FromMils(libPin.PinLength)
                                };
                                break;

                            case LibAttribute libAttribute:
                                if (schComponent.GetParameter(libAttribute.Name) != null)
                                {
                                    break;
                                }
                                var parameterValue = libAttribute.Text;
                                if (string.IsNullOrEmpty(parameterValue) && footprint != null)
                                {
                                    // when the value is empty, and not present in the component, Ultimate Librarian
                                    // gets the parameter value from the fooprint when exporting to Altium
                                    parameterValue = footprint.GetAttribute(libAttribute.Name)?.Text;
                                }
                                if (string.IsNullOrEmpty(parameterValue))
                                {
                                    parameterValue = component.GetAttribute(libAttribute.Name)?.Text;
                                }

                                schPrimitive = new SchParameter
                                {
                                    Location      = ConvertPoint(libAttribute.Origin),
                                    Name          = libAttribute.Name,
                                    Text          = parameterValue ?? string.Empty,
                                    FontId        = GetFontId(schlib, document, libAttribute.TextStyle),
                                    Justification = ConvertJustification(libAttribute.Justify),
                                    Orientation   = ConvertRotatation(libAttribute.Rotate),
                                    IsMirrored    = libAttribute.IsFlipped,
                                    IsHidden      = hideAllParameters || !libAttribute.IsVisible,
                                };
                                break;

                            case LibWizard libWizard:
                                if (schComponent.GetParameter(libWizard.VarName) != null)
                                {
                                    break;
                                }
                                schPrimitive = new SchParameter
                                {
                                    Location = ConvertPoint(libWizard.Origin),
                                    Name     = libWizard.VarName,
                                    Text     = libWizard.VarData
                                };
                                break;

                            case null:
                                break;

                            default:
                                throw new ArgumentOutOfRangeException(nameof(libitem));
                            }

                            if (schPrimitive != null)
                            {
                                schPrimitive.OwnerPartDisplayMode = displayMode;
                                schComponent.Add(schPrimitive);
                            }
                        }

                        displayMode++;
                    }
                }

                schComponent.DisplayMode   = 0;
                schComponent.CurrentPartId = 1;
                schlib.Add(schComponent);
            }

            return(schlib);
        }