public bool ConvertBoardFile(string SourceFilename, string OutputFolder, string ProjectName) { bool result = false; int net_index = 1; DesignRules designRules = new DesignRules(); PartMap = new RenameMap(); k.LayerDescriptor layer; Trace(string.Format("Reading board file {0}", SourceFilename)); board = EagleFile.LoadFromXmlFile(SourceFilename); // if (board != null) { libraryConverter = new LibraryConverter(Parent); ConvertComponentLibraries(OutputFolder, false); k.Pcb.kicad_pcb k_pcb = new k.Pcb.kicad_pcb(); k_pcb.Modules = new List <k.ModuleDef.Module>(); k_pcb.Drawings = new List <k.Pcb.graphic_base>(); // paper and size: get the page size PageStr = "A4"; PageSize = new SizeF(297, 210); foreach (Element element in board.Drawing.Board.Elements.Element) { // if (element.Library == "frames") { //todo: //ConvertFrame(element.Package); break; } } k_pcb.Page = PageStr; // offset from bottom left DrawingOffset = new PointF(2 * Common.inch_to_mm, 2 * Common.inch_to_mm); k_pcb.Setup.grid_origin = StrToPoint_Board("0", "0"); //testFont(k_pcb); // ** debug // get list of part names foreach (Element element in board.Drawing.Board.Elements.Element) { PartMap.Add(element.Name); } PartMap.Annotate(); // layers? #region ==== designrules ==== foreach (Param param in board.Drawing.Board.Designrules.Param) { designRules.Add(param.Name, param.Value); } #endregion #region ==== Plain - text ==== foreach (Text text in board.Drawing.Board.Plain.Text) { bool mirror; int angle = Common.xGetAngleFlip(text.Rot, out mirror); layer = ConvertLayer(text.Layer); if (layer != null) { k.Pcb.gr_text k_text = new k.Pcb.gr_text( text.mText, StrToPoint_Board(text.X, text.Y), layer.Name, new SizeF(Common.StrToVal_mm(text.Size), Common.StrToVal_mm(text.Size)), Common.GetTextThickness_mm(text), angle ); k_text.effects.horiz_align = k.TextJustify.left; SizeF textSize = strokeFont.GetTextSize(text.mText, k_text.effects); PointF offset = new PointF(textSize.Width / 2, textSize.Height / 2); // TODO: spin switch ((int)ExtRotation.Parse(text.Rot).Rotation) { case 0: if (mirror) { k_text.Position.At.Y -= offset.Y; } else { k_text.Position.At.Y -= offset.Y; } break; case 90: if (mirror) { k_text.Position.At.X += offset.Y; k_text.Position.At.Y -= textSize.Width; } else { k_text.Position.At.X -= offset.Y; } break; case 180: if (mirror) { k_text.Position.At.Y += offset.Y; } else { k_text.Position.At.Y += textSize.Height; } break; case 270: if (mirror) { k_text.Position.At.X -= offset.Y; k_text.Position.At.Y += textSize.Width; } else { k_text.Position.At.X += offset.Y; } break; } k_pcb.Drawings.Add(k_text); } } #endregion #region ==== Plain - lines ==== foreach (Wire wire in board.Drawing.Board.Plain.Wire) { layer = ConvertLayer(wire.Layer); if (layer != null) { float width = Common.StrToVal_mm(wire.Width); //todo: arcs k.Pcb.gr_line k_line = new k.Pcb.gr_line( StrToPoint_Board(wire.X1, wire.Y1), StrToPoint_Board(wire.X2, wire.Y2), layer.Name, width ); k_pcb.Drawings.Add(k_line); } } #endregion #region ==== Plain - rectangle ==== // convert to unconnected zones foreach (EagleImport.Rectangle rect in board.Drawing.Board.Plain.Rectangle) { layer = ConvertLayer(rect.Layer); if (layer != null) { PointF p1 = StrToPoint_Board(rect.X1, rect.Y1); PointF p2 = StrToPoint_Board(rect.X2, rect.Y2); k.Pcb.Zone zone = new k.Pcb.Zone(); zone.layer = layer.Name; zone.net = 0; zone.net_name = ""; zone.hatch_pitch = 0.508f; zone.connect_pads_clearance = 0.508f; zone.min_thickness = 0.001f; zone.is_filled = false; zone.fill_arc_segments = 16; zone.fill_thermal_gap = 0.508f; zone.fill_thermal_bridge_width = 0.508f; zone.polygon.Add(new PointF(p1.X, p1.Y)); zone.polygon.Add(new PointF(p2.X, p1.Y)); zone.polygon.Add(new PointF(p2.X, p2.Y)); zone.polygon.Add(new PointF(p1.X, p2.Y)); k_pcb.Zones.Add(zone); // todo : not needed? //k.Pcb.gr_line k_line; //k_line = new k.Pcb.gr_line(new PointF(p1.X, p1.Y), new PointF(p2.X, p1.Y), layer.Name, width); //k_pcb.Drawings.Add(k_line); //k_line = new k.Pcb.gr_line(new PointF(p2.X, p1.Y), new PointF(p2.X, p2.Y), layer.Name, width); //k_pcb.Drawings.Add(k_line); //k_line = new k.Pcb.gr_line(new PointF(p1.X, p2.Y), new PointF(p2.X, p2.Y), layer.Name, width); //k_pcb.Drawings.Add(k_line); //k_line = new k.Pcb.gr_line(new PointF(p1.X, p1.Y), new PointF(p1.X, p2.Y), layer.Name, width); //k_pcb.Drawings.Add(k_line); } } #endregion #region ==== Plain - Hole ==== foreach (Hole hole in board.Drawing.Board.Plain.Hole) { PointF p1 = StrToPoint_Board(hole.X, hole.Y); float drill = Common.StrToVal_mm(hole.Drill); k_pcb.AddModule(NonplatedHole(drill, drill), p1); } #endregion #region ==== plain.dimension ==== foreach (Dimension dim in board.Drawing.Board.Plain.Dimension) { layer = ConvertLayer(dim.Layer); if (layer != null) { PointF p1 = StrToPoint_Board(dim.X1, dim.Y1); PointF p2 = StrToPoint_Board(dim.X2, dim.Y2); PointF p3 = StrToPoint_Board(dim.X3, dim.Y3); float line_width = 0.15f; // default width? float text_size = Common.StrToVal_mm(dim.TextSize); float text_width = Common.GetTextThickness_mm(dim.TextSize, dim.TextRatio); if (!string.IsNullOrEmpty(dim.Width)) { line_width = Common.StrToVal_mm(dim.Width); } switch (dim.Dtype) { case DimensionType.parallel: case DimensionType.radius: case DimensionType.diameter: k.Pcb.Dimension k_dim = new k.Pcb.Dimension(layer.Name, line_width, p1, p2, text_size, text_width, dim.Unit == GridUnit.mm, int.Parse(dim.Precision), dim.Visible == Bool.yes); k_pcb.Dimensions.Add(k_dim); break; //todo : others? } } } #endregion #region ==== plain.polygon ==== foreach (EagleImport.Polygon poly in board.Drawing.Board.Plain.Polygon) { //todo // if layer is tRestrict or bRestrict, create a keepout zone if ((poly.Layer == "41") || (poly.Layer == "42")) { k.Pcb.Zone zone = new k.Pcb.Zone(); if (poly.Layer == "41") { zone.layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nFront_Cu); } else if (poly.Layer == "42") { zone.layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nBack_Cu); } zone.net = 0; zone.net_name = ""; zone.hatch_pitch = 0.508f; zone.connect_pads_clearance = 0; zone.min_thickness = 10.0f; zone.is_filled = false; zone.fill_arc_segments = 16; zone.connect_pads_mode = k.Pcb.ZonePadConnection.yes; //solid zone.fill_thermal_gap = 0.508f; zone.fill_thermal_bridge_width = 0.508f; zone.is_keepout = true; zone.outline_style = k.Pcb.ZoneOutlineStyle.none; zone.keepout_allow_copper_pour = Kicad_utils.Allowed.not_allowed; zone.priority = 7; foreach (Vertex v in poly.Vertex) { zone.polygon.Add(StrToPoint_Board(v.X, v.Y)); } k_pcb.Zones.Add(zone); } } #endregion #region ==== Signals ==== // get net list foreach (Signal signal in board.Drawing.Board.Signals.Signal) { //todo: ? k_pcb.Nets.Add(new k.Pcb.Net(net_index, signal.Name)); net_index++; } List <PinConnection> Contacts = new List <PinConnection>(); foreach (Signal signal in board.Drawing.Board.Signals.Signal) { //todo: ? k.Pcb.Net k_net = k_pcb.Nets.Find(x => x.Name == signal.Name); foreach (Wire wire in signal.Wire) { layer = ConvertLayer(wire.Layer); if (layer != null) { // todo: segment must be on a copper layer? // ignore unrouted if (wire.Layer != "19") { float width = Common.StrToVal_mm(wire.Width); //todo: arcs? k.Pcb.PcbSegment seg = new Kicad_utils.Pcb.PcbSegment(); seg.layer = layer.Name; seg.net = k_net.Number; seg.start = StrToPoint_Board(wire.X1, wire.Y1); seg.end = StrToPoint_Board(wire.X2, wire.Y2); seg.width = width; k_pcb.Segments.Add(seg); Contacts.Add(new PinConnection(signal.Name, seg.start, layer.Name, null, null)); Contacts.Add(new PinConnection(signal.Name, seg.end, layer.Name, null, null)); } } } // contactref foreach (Contactref con_ref in signal.Contactref) { Contacts.Add(new PinConnection(signal.Name, PointF.Empty, null, con_ref.Element, con_ref.Pad)); } //<via x="6.6675" y="49.2125" extent="1-16" drill="0.3" shape="octagon"/> foreach (Via via in signal.Via) { float drill = Common.StrToVal_mm(via.Drill); PointF pos = StrToPoint_Board(via.X, via.Y); float size = Common.StrToVal_mm(via.Diameter); if (size == 0) { size = designRules.CalcViaSize(drill); } k.Pcb.Via k_via = new k.Pcb.Via(pos, size, drill, k.LayerList.StandardLayers.GetLayerName(k.Layer.nFront_Cu), k.LayerList.StandardLayers.GetLayerName(k.Layer.nBack_Cu), k_net.Number); PinConnection p_conn = Contacts.Find(x => x.position.X == k_via.at.X && x.position.Y == k_via.at.Y); if (via.Extent == "1-16") { k_via.topmost_layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nFront_Cu); k_via.backmost_layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nBack_Cu); } else { Trace(string.Format("error : blind/buried via ? {0},{1} {2} {3}", via.X, via.Y, signal.Name, via.Extent)); } if (p_conn == null) { Trace(string.Format("note : loose via converted to pad at {0},{1} net={2}", via.X, via.Y, signal.Name)); k.ModuleDef.Module k_pad = ViaPad(size, drill, k_net); k_pcb.AddModule(k_pad, pos); } else { k_pcb.Vias.Add(k_via); } } foreach (EagleImport.Polygon poly in signal.Polygon) { //<polygon width="0.2032" layer="1" spacing="0.254" isolate="0.254" rank="2"> //defaults are 6 mil float width = 0.1524f; float isolate = 0.1524f; float spacing = 0.1524f; int rank = int.Parse(poly.Rank); layer = ConvertLayer(poly.Layer); if (layer != null) { //todo: clearances etc should come from DesignRules? if (!string.IsNullOrEmpty(poly.Width)) { width = Common.StrToVal_mm(poly.Width); } if (!string.IsNullOrEmpty(poly.Isolate)) { isolate = Common.StrToVal_mm(poly.Isolate); } if (!string.IsNullOrEmpty(poly.Spacing)) { spacing = Common.StrToVal_mm(poly.Spacing); } if (k.Layer.IsCopperLayer(layer.Number) || (poly.Layer == "41") || (poly.Layer == "42")) { k.Pcb.Zone zone = new k.Pcb.Zone(); if (poly.Layer == "41") { zone.layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nFront_Cu); } else if (poly.Layer == "42") { zone.layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nBack_Cu); } else { zone.layer = layer.Name; } zone.net = k_net.Number; zone.net_name = k_net.Name; zone.outline_style = k.Pcb.ZoneOutlineStyle.edge; zone.hatch_pitch = 0.508f; zone.connect_pads_clearance = 0.2032f; zone.min_thickness = width; // ?? zone.fill_arc_segments = 32; zone.fill_thermal_gap = 0.2032f; zone.fill_thermal_bridge_width = 0.2032f; zone.is_filled = false; foreach (Vertex v in poly.Vertex) { zone.polygon.Add(StrToPoint_Board(v.X, v.Y)); } if ((poly.Pour == PolygonPour.cutout) || !k.Layer.IsCopperLayer(layer.Number)) { zone.is_keepout = true; zone.outline_style = k.Pcb.ZoneOutlineStyle.none; zone.keepout_allow_copper_pour = Kicad_utils.Allowed.not_allowed; } if (!string.IsNullOrEmpty(poly.Isolate)) { zone.connect_pads_clearance = isolate; } if (poly.Thermals == Bool.yes) { zone.connect_pads_mode = k.Pcb.ZonePadConnection.thermal_relief; zone.fill_thermal_gap = width + 0.001f; // ** zone.fill_thermal_bridge_width = width + 0.001f; // ** } else { zone.connect_pads_mode = k.Pcb.ZonePadConnection.yes; } // priority on KiCad is opposite to rank zone.priority = 6 - rank; k_pcb.Zones.Add(zone); } } } // } #endregion #region ==== Elements ==== foreach (Element element in board.Drawing.Board.Elements.Element) { //todo: k.ModuleDef.Module k_mod; // find package library : package string footprint_sid = element.Library + ":" + libraryConverter.FootprintNameMap.GetNewName(element.Package); k.ModuleDef.Module k_template = libraryConverter.AllFootprints.Find(x => x.Name == footprint_sid); if (k_template == null) { Trace(string.Format("error: {0} not found", footprint_sid)); } else { k_mod = k_template.Clone(true); k_mod.Name = footprint_sid; k_mod.Reference.Value = PartMap.GetNewName(element.Name); k_mod.At = StrToPoint_Board(element.X, element.Y); if (k_mod.Value != null) { k_mod.Value.Value = element.Value; } k_mod.layer = k.LayerList.StandardLayers.GetLayerName(k.Layer.nFront_Cu); // Set position, orientation ExtRotation elementRot = ExtRotation.Parse(element.Rot); int element_angle = (int)elementRot.Rotation; // get attributes for text foreach (EagleImport.Attribute attrib in element.Attribute) { ExtRotation attrRot = ExtRotation.Parse(attrib.Rot); bool attr_mirror = attrRot.Mirror; int attr_angle = (int)attrRot.Rotation; layer = ConvertLayer(attrib.Layer); if (layer != null) { //k.Symbol.SymbolField sym_field = null; k.ModuleDef.fp_text field = null; switch (attrib.Name) { case "NAME": //sym_field = k_symbol.fReference; field = k_mod.Reference; break; case "VALUE": //sym_field = k_symbol.fValue; field = k_mod.Value; break; // Part? // voltage, current } if (field != null) { field.effects.font.Size = new SizeF(Common.StrToVal_mm(attrib.Size), Common.StrToVal_mm(attrib.Size)); field.layer = layer.Name; field.layer = k.Layer.MakeLayerName(k_mod.layer, field.layer); //field.effects.horiz_align = k.TextJustify.left; //field.effects.vert_align = k.VerticalAlign.bottom; SetPcbTextAttributes(field, StrToPoint_Board(element.X, element.Y), elementRot, StrToPoint_Board(attrib.X, attrib.Y), attrRot); // AdjustPos(field); //debug if (pcb_debug) { PointF ptext = new PointF(field.position.At.X, field.position.At.Y); SizeF textSize = strokeFont.GetTextSize(field.Value, field.effects); if (elementRot.Mirror) { // get bottom right ptext.X += textSize.Width / 2; ptext.Y += textSize.Height / 2; ptext = ptext.Rotate(-elementRot.Rotation - 180); ptext.Y = -ptext.Y; } else { // get bottom left ptext.X -= textSize.Width / 2; ptext.Y += textSize.Height / 2; ptext = ptext.Rotate(-elementRot.Rotation); } ptext = k_mod.position.At.Add(ptext); //!DrawRect(k_pcb, ptext, textSize, -(elementRot.Rotation + field.position.Rotation)); // PointF p1 = new PointF(field.position.At.X, field.position.At.Y); k.Pcb.gr_line k_line; float ds = 1.27f; if (elementRot.Mirror) { p1 = p1.Rotate(-elementRot.Rotation - 180); p1.Y = -p1.Y; } else { p1 = p1.Rotate(-elementRot.Rotation); } //p1 = p1.Rotate(field.position.Rotation); //p1 = p1.Rotate(k_mod.position.Rotation); k_line = new k.Pcb.gr_line( new PointF(k_mod.position.At.X + p1.X - ds, k_mod.position.At.Y + p1.Y), new PointF(k_mod.position.At.X + p1.X + ds, k_mod.position.At.Y + p1.Y), "Dwgs.User", 0.01f); k_pcb.Drawings.Add(k_line); k_line = new k.Pcb.gr_line( new PointF(k_mod.position.At.X + p1.X, k_mod.position.At.Y + p1.Y - ds), new PointF(k_mod.position.At.X + p1.X, k_mod.position.At.Y + p1.Y + ds), "Dwgs.User", 0.01f); k_pcb.Drawings.Add(k_line); } } } } // Note: the Eagle "mirror" attribute reverses side and flips about Y | axis, but // Kicad "flip" reverses side and flips about X -- axis. // therefore Eagle mirror is equivalent to Kicad flip + rotate(180) if (elementRot.Mirror) { k_mod.RotateBy(MathUtil.NormalizeAngle(-(element_angle + 180))); k_mod.FlipX(k_mod.position.At); } else //if (element_angle != 0) { k_mod.RotateBy(element_angle); } // fix up pads foreach (k.ModuleDef.pad pad in k_mod.Pads) { string new_name = PartMap.GetNewName(element.Name); if (pad.type != k.ModuleDef.pad.nonplated_hole) { PinConnection contact = Contacts.Find(x => x.PartName == element.Name && x.PinName == pad.number); if (contact == null) { // may actually be a non-connect // Trace(string.Format("warning: contact {0} {1} not found", element.Name, pad.number)); } else { pad.net = k_pcb.Nets.Find(x => x.Name == contact.NetLabel); } } } // k_pcb.Modules.Add(k_mod); } } #endregion // transfer some design rules k_pcb.Setup.trace_min = designRules.GetValueFloat("msWidth"); k_pcb.Setup.via_min_size = designRules.GetValueFloat("msWidth"); k_pcb.Setup.via_min_drill = designRules.GetValueFloat("msDrill"); k_pcb.Setup.uvia_min_size = designRules.GetValueFloat("msMicroVia"); k_pcb.Setup.uvia_min_drill = designRules.GetValueFloat("msMicroVia"); // not right, but need layer thickness to calculate correctly // allow uvia // allow blind/buried via // grid // text and drawings // pad // pad mask clearance //default netclass k_pcb.NetClasses[0].clearance = designRules.GetValueFloat("mdPadVia"); k_pcb.NetClasses[0].trace_width = designRules.GetValueFloat("msWidth"); k_pcb.NetClasses[0].via_dia = designRules.GetValueFloat("msWidth"); k_pcb.NetClasses[0].via_drill = designRules.GetValueFloat("msDrill"); k_pcb.NetClasses[0].uvia_dia = designRules.GetValueFloat("msMicroVia"); k_pcb.NetClasses[0].uvia_drill = designRules.GetValueFloat("msMicroVia"); // not right // write the KiCad file string filename = Path.Combine(OutputFolder, ProjectName + ".kicad_pcb"); Trace(string.Format("Writing board {0}", filename)); k_pcb.SaveToFile(filename); result = true; } else { result = false; Trace(string.Format("error opening {0}", SourceFilename)); } return(result); }
private void ConvertSheet(k.Schema.SchematicLegacy k_schematic, int EagleSheetNumber, string DestName, bool IsMain, int SheetNumber, int NumSheets) { List <PinConnection> connections = new List <PinConnection>(); List <LineSegment> BusLines = new List <LineSegment>(); Trace(string.Format("Processing schematic sheet: {0}", EagleSheetNumber + 1)); Sheet source_sheet = schematic.Drawing.Schematic.Sheets.Sheet[EagleSheetNumber]; SheetLegacy k_sheet = new SheetLegacy(); k_sheet.Filename = DestName; k_sheet.LibNames = libraryConverter.LibNames; k_sheet.SheetNumber = SheetNumber; k_sheet.SheetCount = NumSheets; k_schematic.Sheets.Add(k_sheet); if (IsMain) { k_schematic.MainSheet = k_sheet; } // first get the page size foreach (Instance instance in source_sheet.Instances.Instance) { // find part -> Part part = FindPart(instance.Part); if (part == null) { continue; } // if (part.Library == "frames") { PageStr = "A4"; PageSize = new SizeF(297, 210); ConvertFrame(part.Deviceset); k_sheet.PaperName = PageStr; k_sheet.PageSize = new SizeF(PageSize.Width * Common.mm_to_mil, PageSize.Height * Common.mm_to_mil); break; } } // text items foreach (Text text in source_sheet.Plain.Text) { bool mirror; k.Schema.sch_text k_text = sch_text.CreateNote( text.mText, StrToPointInchFlip(text.X, text.Y), Common.StrToInch(text.Size), Common.xGetAngleFlip(text.Rot, out mirror), false, false); switch (Common.GetAngle(text.Rot)) { case 0: break; case 90: if (mirror) { k_text.Pos.X += (int)(k_text.TextSize * 1.5f); k_text.Pos.Y -= (int)(k_text.name.Length * k_text.TextSize * 1.5f); } break; case 180: k_text.Pos.Y += (int)(k_text.TextSize * 1.5f); break; case 270: if (mirror) { //k_text.Pos.X += (int)(k_text.TextSize * 1.5f); k_text.Pos.Y += (int)(k_text.name.Length * k_text.TextSize * 1.7f); } else { k_text.Pos.X += (int)(k_text.TextSize * 1.5f); } break; } k_sheet.Items.Add(k_text); } // lines foreach (Wire wire in source_sheet.Plain.Wire) { k.Schema.sch_wire k_line = sch_wire.CreateLine(StrToPointInchFlip(wire.X1, wire.Y1), StrToPointInchFlip(wire.X2, wire.Y2)); k_sheet.Items.Add(k_line); } #region === (Instance) components ==== foreach (Instance instance in source_sheet.Instances.Instance) { // find part -> Part part = FindPart(instance.Part); if (part == null) { Trace("error: Part not found: " + instance.Part); continue; } if (part.Library == "frames") { continue; } k.Symbol.Symbol k_symbol = FindSymbol(part.Deviceset); LegacyComponent k_comp = new LegacyComponent(); k_comp.Timestamp = GetUniqueTimeStamp(); // need to flip Y coord k_comp.Position = StrToPointInchFlip(instance.X, instance.Y); k_comp.Symbol = new PartSpecifier(part.Deviceset + part.Device); // set Reference field if (!k_symbol.PowerSymbol) { k_comp.Reference = PartMap.GetNewName(instance.Part); if (instance.Part != k_comp.Reference) { Trace(String.Format("note: {0} is renamed {1}", instance.Part, k_comp.Reference)); } } else { k_comp.Reference = k_symbol.Reference; k_comp.fReference.Hidden = !k_symbol.fReference.Text.Visible; k_comp.fReference.Size = (int)k_symbol.fReference.Text.FontSize; } // set a default pos/ k_comp.fReference.Pos = new PointF(k_comp.Position.X + k_symbol.fReference.Text.Pos.At.X, k_comp.Position.Y + k_symbol.fReference.Text.Pos.At.Y); k_comp.fReference.HorizJustify = "L"; k_comp.fReference.VertJustify = "B"; // Set Value field if (!string.IsNullOrEmpty(part.Value)) { k_comp.Value = part.Value; } else { k_comp.Value = k_symbol.fValue.Text.Value; } k_comp.fValue.Pos = new PointF(k_comp.Position.X + k_symbol.fValue.Text.Pos.At.X, k_comp.Position.Y + k_symbol.fValue.Text.Pos.At.Y); k_comp.fValue.HorizJustify = "L"; k_comp.fValue.VertJustify = "B"; // Set Footprint field Device device = libraryConverter.AllDevices.Find(x => x.Name == part.Deviceset + part.Device); if (device != null) { k_comp.Footprint = part.Library + ":" + device.Package; } k_comp.fPcbFootprint.Pos = new PointF(k_comp.Position.X, k_comp.Position.Y); k_comp.fPcbFootprint.Hidden = true; // User doc field (not used) k_comp.fUserDocLink.Pos = new PointF(k_comp.Position.X, k_comp.Position.Y); // if (k_symbol.NumUnits > 1) { int unit = GetUnitNumber(part, instance.Gate); k_comp.N = unit; } // --------------------------------- // Set position, orientation ExtRotation instanceRot = ExtRotation.Parse(instance.Rot); bool instance_mirror = instanceRot.Mirror; int instance_angle = (int)instanceRot.Rotation; if (!string.IsNullOrEmpty(instance.Rot)) { if (instance_mirror) { k_comp.Rotation = (instance_angle + 180) % 360; } else { k_comp.Rotation = instance_angle; } k_comp.Mirror = instance_mirror; } foreach (EagleImport.Attribute attrib in instance.Attribute) { ExtRotation attrRot = ExtRotation.Parse(attrib.Rot); bool attr_mirror = attrRot.Mirror; int attr_angle = (int)attrRot.Rotation; //int angle = GetAngle(attrib.Rot); //angle %= 360; //string orientation = (angle == 0) || (angle == 180) ? "H" : "V"; k.Symbol.SymbolField sym_field = null; LegacyField field = null; switch (attrib.Name) { case "NAME": sym_field = k_symbol.fReference; field = k_comp.fReference; //field.Pos = new PointF(k_comp.Position.X + k_symbol.fReference.Text.Pos.X, k_comp.Position.Y + k_symbol.fReference.Text.Pos.Y); break; case "VALUE": sym_field = k_symbol.fValue; field = k_comp.fValue; //field.Pos = new PointF(k_comp.Position.X + k_symbol.fValue.Text.Pos.X, k_comp.Position.Y + k_symbol.fValue.Text.Pos.Y); break; //Part? // voltage, current } if (field != null) { field.Size = (int)Common.StrToInch(attrib.Size); SetFieldAttributes(field, StrToPointInchFlip(attrib.X, attrib.Y), //sym_field.Text.xAngle, sym_field.Text.xMirror, k_comp.Position, attr_angle, attr_mirror); instance_angle, k_comp.Mirror, k_comp.Position, attr_angle, attr_mirror); //PointF p = Common.StrToPointInchFlip (attrib.X, attrib.Y); //field.Pos = Common.StrToPointInchFlip(attrib.X, attrib.Y); //debug // field pos rotated about comp pos PointF p = PointFExt.Rotate(field.Pos, k_comp.Position, k_comp.Rotation); k.Schema.sch_wire k_line; //// field pos + ////PointF p = field.Pos; //k_line = sch_wire.CreateLine(new PointF(p.X - 25, p.Y), new PointF(p.X + 25, p.Y)); //k_sheet.Items.Add(k_line); //k_line = sch_wire.CreateLine(new PointF(p.X, p.Y - 25), new PointF(p.X, p.Y + 25)); //k_sheet.Items.Add(k_line); // actual coord of attribute |__ //p = Common.StrToPointInchFlip(attrib.X, attrib.Y); //k_line = sch_wire.CreateLine(new PointF(p.X-50, p.Y), new PointF(p.X + 50, p.Y)); //k_sheet.Items.Add(k_line); //k_line = sch_wire.CreateLine(new PointF(p.X, p.Y-50), new PointF(p.X, p.Y + 50)); //k_sheet.Items.Add(k_line); } } // AllComponents.Add(k_comp); k_sheet.Components.Add(k_comp); } #endregion #region ==== Busses ==== foreach (Bus bus in source_sheet.Busses.Bus) { foreach (Segment segment in bus.Segment) { foreach (Wire wire in segment.Wire) { k.Schema.sch_wire k_bus = sch_wire.CreateBus(StrToPointInchFlip(wire.X1, wire.Y1), StrToPointInchFlip(wire.X2, wire.Y2)); k_sheet.Items.Add(k_bus); BusLines.Add(new LineSegment(Vector2Ext.ToVector2(k_bus.start), Vector2Ext.ToVector2(k_bus.end))); } } } #endregion #region ==== (Net) look for wires, junctions, labels ==== foreach (Net net in source_sheet.Nets.Net) { foreach (Segment segment in net.Segment) { List <Vector2> snap_points = new List <Vector2>(); List <LineSegment> snap_lines = new List <LineSegment>(); foreach (Wire wire in segment.Wire) { PointF start = StrToPointInchFlip(wire.X1, wire.Y1); PointF end = StrToPointInchFlip(wire.X2, wire.Y2); Vector2 p1 = Vector2Ext.ToVector2(start); Vector2 p2 = Vector2Ext.ToVector2(end); bool is_bus_entry = false; foreach (LineSegment line in BusLines) { if (line.Contains(p1) || line.Contains(p2)) { is_bus_entry = true; } } if (is_bus_entry) { sch_wire k_wire = sch_wire.CreateWireToBusEntry(start, end); k_sheet.Items.Add(k_wire); } else { sch_wire k_wire = sch_wire.CreateWire(start, end); k_sheet.Items.Add(k_wire); //snap_points.Add(Vector2Ext.ToVector2(k_wire.start)); //snap_points.Add(Vector2Ext.ToVector2(k_wire.end)); snap_lines.Add(new LineSegment(Vector2Ext.ToVector2(k_wire.start), Vector2Ext.ToVector2(k_wire.end))); } } foreach (Junction junction in segment.Junction) { sch_Junction k_junction = new sch_Junction(StrToPointInchFlip(junction.X, junction.Y)); k_sheet.Items.Add(k_junction); snap_points.Add(Vector2Ext.ToVector2(k_junction.Pos)); } //todo: add gate positions to snap_points foreach (Pinref pinref in segment.Pinref) { Part part = FindPart(pinref.Part); k.Symbol.Symbol k_symbol = FindSymbol(part.Deviceset); // get comp ... PinConnection connect = connections.Find(x => x.Part == part && x.GateId == pinref.Gate && x.PinName == pinref.Pin); if (connect == null) { connect = new PinConnection(net.Name, part, pinref.Gate, pinref.Pin); connections.Add(connect); } } foreach (Label label in segment.Label) { ExtRotation rot = ExtRotation.Parse(label.Rot); int angle = (int)rot.Rotation; if (rot.Mirror) { if ((angle % 180) == 0) { angle = 180 - angle; } } //angle %= 360; sch_text k_text = sch_text.CreateLocalLabel(net.Name, StrToPointInchFlip(label.X, label.Y), Common.StrToInch(label.Size), angle); // find nearest point //k_text.Pos = FindSnapPoint(snap_points, k_text.Pos); k_text.Pos = FindNearestPoint(snap_points, snap_lines, Vector2Ext.ToVector2(StrToPointInchFlip(label.X, label.Y))); k_sheet.Items.Add(k_text); AllLabels.Add(new PinConnection(k_text, k_sheet)); } } } #endregion #region add no-connects if (option_add_no_connects) { foreach (Instance instance in source_sheet.Instances.Instance) { // find part -> Part part = FindPart(instance.Part); if (part == null) { //Trace("Part not found: " + instance.Part); continue; } if (part.Library == "frames") { continue; } k.Symbol.Symbol k_symbol = FindSymbol(part.Deviceset); // List <PinConnection> pins = connections.FindAll(x => x.Part.Name == instance.Part && x.GateId == instance.Gate); foreach (PinConnection p in pins) { // Trace(string.Format("Part {0,-10} Gate {1,-10} Pin {2,-10} Net {3,-10}", p.Part.Name, p.GateId, p.PinName, p.NetLabel)); } // List <PinConnection> NoConnects = new List <PinConnection>(); Symbol symbol = FindSymbol(part, instance.Gate); foreach (Pin pin in symbol.Pin) { PinConnection conn = connections.Find(x => x.Part == part && x.GateId == instance.Gate && x.PinName == pin.Name); if (conn == null) { //Trace(string.Format("Part {0,-10} Gate {1,-10} Pin {2,-10}", part.Name, instance.Gate, pin.Name)); NoConnects.Add(new PinConnection(null, part, instance.Gate, pin.Name)); // todo: add no-connects PointF instance_pos = StrToPointInchFlip(instance.X, instance.Y); PointF pin_pos = Common.StrToPointInch(pin.X, pin.Y); ExtRotation rot = ExtRotation.Parse(instance.Rot); pin_pos = PointFExt.Rotate(pin_pos, (int)rot.Rotation); if (rot.Mirror) { pin_pos = new PointF(-pin_pos.X, pin_pos.Y); } PointF pos = new PointF(instance_pos.X + pin_pos.X, instance_pos.Y - pin_pos.Y); sch_NoConnect k_noconn = new sch_NoConnect(pos); k_sheet.Items.Add(k_noconn); } } } } #endregion }