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 }
// this method was derived from: // https://github.com/lachlanA/eagle-to-kicad/blob/master/eagle6xx-sch-to-kicad-sch.ulp#L1181 private void SetFieldAttributes(LegacyField field, PointF text_pos, float instance_angle, bool instance_mirror, PointF comp_pos, int attr_angle, bool attr_mirror) { int i_angle = (int)instance_angle; int x = (int)text_pos.X; int y = (int)text_pos.Y; // calculate text position from origin of component int diffX = (int)comp_pos.X - x; int diffY = (int)comp_pos.Y - y; if (!instance_mirror) { diffY = -diffY; instance_angle = instance_angle + 180; } // rotate offset position about origin by rotation degrees (clockwise) int px, py; px = (int)(Math.Cos(MathUtil.DegToRad(instance_angle)) * diffX + Math.Sin(MathUtil.DegToRad(instance_angle)) * diffY); py = (int)(-Math.Sin(MathUtil.DegToRad(instance_angle)) * diffX + Math.Cos(MathUtil.DegToRad(instance_angle)) * diffY); x = (int)(comp_pos.X + px); y = (int)(comp_pos.Y + py); field.Pos = new PointF(x, y); // now figure orientation, alignment char orient = 'H'; char hAlign = 'L'; char vAlign = 'B'; switch (i_angle) { case 0: // angle switch (attr_angle) { case 0: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'H'; hAlign = 'L'; vAlign = 'B'; } break; case 90: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } //** break; case 180: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'H'; hAlign = 'R'; vAlign = 'T'; } break; case 270: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'V'; hAlign = 'R'; vAlign = 'T'; } //** break; } break; case 180: // angle switch (attr_angle) { case 0: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'H'; hAlign = 'R'; vAlign = 'T'; } break; case 90: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'V'; hAlign = 'R'; vAlign = 'T'; } // break; case 180: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'H'; hAlign = 'L'; vAlign = 'B'; } break; case 270: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } // break; } break; case 90: // angle switch (attr_angle) { case 0: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'V'; hAlign = 'R'; vAlign = 'T'; } //vh break; case 90: if (instance_mirror) { if (attr_mirror) { orient = 'H'; hAlign = 'L'; vAlign = 'B'; } else { orient = 'H'; hAlign = 'L'; vAlign = 'T'; } } else { if (attr_mirror) { orient = 'H'; hAlign = 'L'; vAlign = 'T'; } // v else { orient = 'H'; hAlign = 'L'; vAlign = 'B'; } } break; case 180: if (instance_mirror) { if (attr_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } // else { orient = 'V'; hAlign = 'R'; vAlign = 'B'; } } else { if (attr_mirror) { orient = 'V'; hAlign = 'R'; vAlign = 'B'; } //h else { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } //** } break; case 270: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'H'; hAlign = 'R'; vAlign = 'T'; } break; } break; case 270: // angle switch (attr_angle) { case 0: if (instance_mirror) { if (attr_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } else { orient = 'V'; hAlign = 'R'; vAlign = 'B'; } } else { if (attr_mirror) { orient = 'V'; hAlign = 'R'; vAlign = 'T'; } else { orient = 'V'; hAlign = 'L'; vAlign = 'B'; } // } break; case 180: if (attr_mirror ^ instance_mirror) { orient = 'V'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'V'; hAlign = 'R'; vAlign = 'T'; } // break; case 90: // !! if (instance_mirror) { orient = 'H'; hAlign = 'R'; vAlign = 'B'; } else { orient = 'H'; hAlign = 'R'; vAlign = 'T'; } break; case 270: if (attr_mirror ^ instance_mirror) { orient = 'H'; hAlign = 'L'; vAlign = 'T'; } else { orient = 'H'; hAlign = 'L'; vAlign = 'B'; } break; } break; } // switch field.Orientation = orient.ToString(); field.HorizJustify = hAlign.ToString(); field.VertJustify = vAlign.ToString(); }