private void GetSymbol(Library lib, Deviceset devset, k.Symbol.Symbol k_sym) { bool is_multi_part = false; bool interchangeable_units = false; string symbol_name = devset.Gates.Gate[0].Symbol; if (devset.Gates.Gate.Count == 1) { is_multi_part = false; } else { is_multi_part = true; interchangeable_units = true; foreach (Gate gate in devset.Gates.Gate) { if (symbol_name != gate.Symbol) { interchangeable_units = false; break; } } k_sym.NumUnits = devset.Gates.Gate.Count; if (interchangeable_units) { k_sym.Locked = false; } else { k_sym.Locked = true; } } int gate_index = 0; k_sym.ShowPinName = true; k_sym.ShowPinNumber = true; foreach (Gate gate in devset.Gates.Gate) { Symbol sym = lib.Symbols.Symbol.Find(x => x.Name == gate.Symbol); if (sym == null) { Trace("error: symbol not found: " + gate.Symbol); return; } if ((lib.Name != null) && lib.Name.StartsWith("supply")) { k_sym.PowerSymbol = true; k_sym.Reference = "#PWR"; k_sym.fReference.Text.Value = "#PWR"; k_sym.fReference.Text.Visible = false; } int unit = 0; //int convert = 1; if (is_multi_part && !interchangeable_units) { unit = gate_index + 1; } if ((gate_index == 0) || (is_multi_part && !interchangeable_units)) { // graphic lines, arcs foreach (Wire wire in sym.Wire) { float curve = (float)StringUtils.StringToDouble(wire.Curve); if (curve == 0) { k_sym.Drawings.Add(new k.Symbol.sym_polygon(unit, Common.StrToInch(wire.Width), k.Symbol.FillTypes.None, new List <PointF>() { Common.StrToPointInch(wire.X1, wire.Y1), Common.StrToPointInch(wire.X2, wire.Y2) })); } else { PointF start = Common.StrToPointInch(wire.X1, wire.Y1); PointF end = Common.StrToPointInch(wire.X2, wire.Y2); float arc_start, arc_end, radius; PointF center = Common.kicad_arc_center(start, end, -curve, out radius, out arc_start, out arc_end); k_sym.Drawings.Add(new k.Symbol.sym_arc(unit, Common.StrToInch(wire.Width), center, radius, arc_start, arc_end, start, end)); } } // graphic : circles foreach (Circle circle in sym.Circle) { float width = 1; if (!string.IsNullOrEmpty(circle.Width)) { width = Math.Max(Common.StrToInch(circle.Width), 1); } k_sym.Drawings.Add(new k.Symbol.sym_circle(unit, width, k.Symbol.FillTypes.None, Common.StrToPointInch(circle.X, circle.Y), Common.StrToInch(circle.Radius))); } // graphic : rectangles foreach (EagleImport.Rectangle rect in sym.Rectangle) { k_sym.Drawings.Add(new k.Symbol.sym_rectangle(unit, 1f, k.Symbol.FillTypes.PenColor, Common.StrToPointInch(rect.X1, rect.Y1), Common.StrToPointInch(rect.X2, rect.Y2))); } // graphic : texts // check for name, value foreach (Text text in sym.Text) { k.Symbol.sym_text k_text = new k.Symbol.sym_text(unit, text.mText, 0, Common.StrToPointInch(text.X, text.Y), Common.StrToInch(text.Size), false, false, false, k.Symbol.SymbolField.HorizAlign_Left, k.Symbol.SymbolField.VertAlign_Bottom); //ExtRotation extRot = ExtRotation.Parse(text.Rot); k_text.Text.xAngle = Common.GetAngle(text.Rot); k_text.Text.Pos.Rotation = Common.xGetAngleFlip(text.Rot, out k_text.Text.xMirror); SizeF textSize = strokeFont.GetTextSize(text.mText, new Kicad_utils.TextEffects(k_text.Text.FontSize)); string t = text.mText.ToUpperInvariant(); if (t.Contains(">NAME") || t.Contains(">PART") || t.Contains(">VALUE")) { k.Symbol.SymbolField sym_text; if (t.Contains(">VALUE")) { sym_text = k_sym.fValue; } else { sym_text = k_sym.fReference; } sym_text.Text.Pos = k_text.Text.Pos; sym_text.Text.FontSize = k_text.Text.FontSize; if ((k_text.Text.Pos.Rotation == 0) || (k_text.Text.Pos.Rotation == 180)) { sym_text.Text.Pos.Rotation = 0; } else { sym_text.Text.Pos.Rotation = 90; } } else { // unless Spin is set? if (k_text.Text.Pos.Rotation == 180) { k_text.Text.Pos.At.X -= textSize.Width; k_text.Text.Pos.At.Y -= textSize.Height; k_text.Text.Pos.Rotation = 0; } // k_sym.Drawings.Add(k_text); } } } // Pins foreach (Pin pin in sym.Pin) { k.Symbol.sym_pin k_pin = new k.Symbol.sym_pin(unit, Common.ConvertName(pin.Name), "~", Common.StrToPointInch(pin.X, pin.Y), 250, "L", 50f, 50f, "P", "", true); switch (pin.Rot) { case "R0": k_pin.Orientation = "R"; break; case "R90": k_pin.Orientation = "U"; break; case "R180": k_pin.Orientation = "L"; break; case "R270": k_pin.Orientation = "D"; break; default: k_pin.Orientation = "R"; break; } switch (pin.Length) { case PinLength.point: k_pin.Length = 0; break; case PinLength.@short: k_pin.Length = 100; break; case PinLength.middle: k_pin.Length = 200; break; case PinLength.@long: k_pin.Length = 300; break; default: k_pin.Length = 300; break; } switch (pin.Visible) { case PinVisible.off: k_pin.SizeName = 0; k_pin.SizeNum = 0; break; case PinVisible.pad: k_pin.SizeName = 0; break; case PinVisible.pin: k_pin.SizeNum = 0; break; case PinVisible.both: break; } switch (pin.Direction) { case PinDirection.nc: k_pin.Type = "N"; break; case PinDirection.@in: k_pin.Type = "I"; break; case PinDirection.@out: k_pin.Type = "O"; break; case PinDirection.io: k_pin.Type = "B"; break; case PinDirection.oc: k_pin.Type = "C"; break; case PinDirection.hiz: k_pin.Type = "T"; break; case PinDirection.pas: k_pin.Type = "P"; break; case PinDirection.pwr: k_pin.Type = "W"; break; case PinDirection.sup: k_pin.Type = "w"; break; default: k_pin.Type = "B"; break; } if (k_sym.PowerSymbol) { k_pin.Type = k.Symbol.sym_pin.dir_power_in; k_pin.PinNumber = "~"; k_pin.Visible = false; // todo add line... if (k_pin.Length != 0) { PointF p1 = k_pin.Pos; PointF p2 = new PointF(k_pin.Pos.X + k_pin.Length, k_pin.Pos.Y); p2 = PointFExt.Rotate(p2, k_pin.Pos, Common.GetAngle(pin.Rot)); k_sym.Drawings.Add(new k.Symbol.sym_polygon(unit, 6, k.Symbol.FillTypes.None, new List <PointF>() { p1, p2 })); } } switch (pin.Function) { case PinFunction.none: k_pin.Shape = ""; break; case PinFunction.dot: k_pin.Shape = "I"; break; case PinFunction.clk: k_pin.Shape = "C"; break; case PinFunction.dotclk: k_pin.Shape = "CI"; break; } // k_sym.Drawings.Add(k_pin); } gate_index++; } // foreach gate }
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 }