using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Threading.Tasks; using System.Windows.Forms; using System.IO; using Prosoft.ECAD.CommonTypes; namespace Prosoft.ECAD.Script { [ScriptClass] public class Script : ScriptBase { struct TTrackSegment_ { public float x; public float y; public float w; } struct TTrack { public float x; public float y; public TTrackSegment_[] segments; public string net; public string layer; } struct TVia { public double x; public double y; public string net; public string style; } struct TComponent { public double x; public double y; public string designator; public MountSide mountSide; public int angle; } public static DialogResult InputBox(string title, string promptText, ref string value) { Form form = new Form(); Label label = new Label(); TextBox textBox = new TextBox(); Button buttonOk = new Button(); Button buttonCancel = new Button(); form.Text = title; label.Text = promptText; textBox.Text = value; buttonOk.Text = "OK"; buttonCancel.Text = "Cancel"; buttonOk.DialogResult = DialogResult.OK; buttonCancel.DialogResult = DialogResult.Cancel; label.SetBounds(9, 15, 372, 13); textBox.SetBounds(12, 36, 372, 20); buttonOk.SetBounds(228, 72, 75, 23); buttonCancel.SetBounds(309, 72, 75, 23); label.AutoSize = true; textBox.Anchor = textBox.Anchor | AnchorStyles.Right; buttonOk.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonCancel.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; form.ClientSize = new Size(396, 107); form.Controls.AddRange(new Control[] { label, textBox, buttonOk, buttonCancel }); form.ClientSize = new Size(Math.Max(300, label.Right + 10), form.ClientSize.Height); form.FormBorderStyle = FormBorderStyle.FixedDialog; form.StartPosition = FormStartPosition.CenterScreen; form.MinimizeBox = false; form.MaximizeBox = false; form.AcceptButton = buttonOk; form.CancelButton = buttonCancel; DialogResult dialogResult = form.ShowDialog(); value = textBox.Text; return dialogResult; } public async Task Main() { if (MessageBox.Show( "Скрипт актуализирован?", "Актуальность скрипта", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.No) return; string blok_desig = "A29"; string proj_name = "Ст20"; OpenFileDialog OPF = new OpenFileDialog(); OPF.Title = "Выберите файл скрипта платы"; OPF.Filter = "Script files(*.cs)|*.cs|All files(*.*)|*.*"; if (OPF.ShowDialog() == DialogResult.Cancel) return; string[] arStr = File.ReadAllLines(OPF.FileName); if (arStr[15].IndexOf("OpenPcb") != -1) { proj_name = arStr[15].Split('(')[1].Split(')')[0].Trim(new char[] {'"'}); } if (InputBox("Опорный блок", "Введите номер опорного блока:", ref blok_desig) == DialogResult.Cancel) return; //******************************************************************************** // нахождение всех подобных блоков //******************************************************************************** var schematic = await OpenSchematic(proj_name); var info_blok_root = schematic.GetComponentInfo(blok_desig); var blok_name = info_blok_root.Part.Attribute[0].Value; Log.WriteLine("Опорный блок: " + blok_desig + " " + blok_name); var list_bl = new List { }; foreach (var c in schematic.Components) { var componentInfo = schematic.GetComponentInfo(c); if (componentInfo.Family == "BLOCK") if (componentInfo.Part.Attribute[0].Value == blok_name && componentInfo.Designator != blok_desig) { if (MessageBox.Show( "Добавить блок " + componentInfo.Designator + " в список модифицируемых?", "Добавление блока в список", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes) { list_bl.Add(componentInfo.Designator); } } } if (list_bl.Count() == 0) { MessageBox.Show( "Не выбраны блоки для модификации!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return; } //******************************************************************************** var components = new Dictionary(); var components_opor = new Dictionary(); var state = 1; var isSegmets = false; var track = new TTrack(); var via = new TVia(); var comp = new TComponent(); var ls_tacks_op = new List { }; var ls_via_op = new List { }; var flag = true; //int deb_c = 0; Log.WriteLine("перебор строк файла"); for (int i = 31; i < arStr.Length; i++) { //if (deb_c > 100) //return; switch (state) { case 1: //определение состояния if (arStr[i].IndexOf("pcb.PlaceComponent") != -1) { state = 2; comp = new TComponent(); comp.mountSide = new MountSide(); //Log.WriteLine("PlaceComponent " + i.ToString()); } else if (arStr[i].IndexOf("pcb.PlaceTrack") != -1) { state = 3; track = new TTrack(); track.segments = new TTrackSegment_[0]; //track.segments = new List { }; //Log.WriteLine("PlaceTrack " + i.ToString()); } else if (arStr[i].IndexOf("pcb.PlaceVia") != -1) { state = 4; via = new TVia(); //Log.WriteLine("PlaceVia " + i.ToString()); } break; case 2: if (arStr[i].IndexOf("location") != -1) { var point = arStr[i].Split('(')[1].Split(','); comp.x = float.Parse(point[0].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); comp.y = float.Parse(point[1].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); if (comp.designator.IndexOf(blok_desig) != -1) components_opor[comp.designator.Split('-')[1]] = comp; else components[comp.designator] = comp; state = 1; //Log.WriteLine("comp " + comp.designator); //deb_c++; } /* else if (arStr[i].IndexOf("mountSide") != -1) if (arStr[i].IndexOf("Top") != -1) comp.mountSide = MountSide.Top; else if (arStr[i].IndexOf("Bottom") != -1) comp.mountSide = MountSide.Bottom; else if (arStr[i].IndexOf("Internal") != -1) comp.mountSide = MountSide.Internal; */ else if (arStr[i].IndexOf("angle") != -1) comp.angle = int.Parse(arStr[i].Split(':')[1].Trim(new char[] { ',', ' '})); else if (arStr[i].IndexOf("designator") != -1) { flag = true; foreach (var bl in list_bl) { if (arStr[i].IndexOf(bl + "-") != -1 || arStr[i].IndexOf(blok_desig + "-") != -1) { comp.designator= arStr[i].Split('"')[1]; flag = false; break; } } if (flag) state = 1; } break; case 3: if (isSegmets) { var seg = new TTrackSegment_(); var Buf = arStr[i].Split('F')[1].Split(','); seg.x = float.Parse(Buf[0].Trim(new char[] { '(', ' ', 'f'}).Replace('.', ',')); seg.y = float.Parse(Buf[1].Trim(new char[] { ')', ' ', 'f'}).Replace('.', ',')); seg.w = float.Parse(Buf[2].Split('=')[1].Trim(new char[] { '}', ' ', ','}).Replace('.', ',')); Array.Resize(ref track.segments, track.segments.Length + 1); track.segments[track.segments.Length - 1] = seg; if (arStr[i][arStr[i].Length-1] == '}') isSegmets = false; } else { if (arStr[i].IndexOf("start") != -1) { var point = arStr[i].Split('(')[1].Split(','); track.x = float.Parse(point[0].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); track.y = float.Parse(point[1].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); } else if (arStr[i].IndexOf("segments") != -1) isSegmets = true; else if (arStr[i].IndexOf("net") != -1) { if (arStr[i].IndexOf(blok_desig + "-") != -1) track.net = arStr[i].Split('"')[1]; else state = 1; } else if (arStr[i].IndexOf("layer") != -1) { track.layer = arStr[i].Split('"')[1]; ls_tacks_op.Add(track); //Log.WriteLine("track " + track.net + " seg:" + track.segments.Count().ToString() + " lay:" + track.layer); //deb_c++; state = 1; } } break; case 4: if (arStr[i].IndexOf("location") != -1) { var point = arStr[i].Split('(')[1].Split(','); via.x = float.Parse(point[0].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); via.y = float.Parse(point[1].Trim(new char[] { 'f', ' ', ')', '(', ',' }).Replace('.', ',')); } else if (arStr[i].IndexOf("style") != -1) via.style = arStr[i].Split('"')[1]; else if (arStr[i].IndexOf("net") != -1) { if (arStr[i].IndexOf(blok_desig + "-") != -1) { via.net = arStr[i].Split('"')[1]; ls_via_op.Add(via); //Log.WriteLine("via " + via.net); //deb_c++; } state = 1; } break; } } var op_component_name = components_opor.Keys.ElementAt(0); if (MessageBox.Show( "Опорный компонент - " + op_component_name + " ?", "Выбор опорного компонента", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.No) { if (InputBox("Опорный компонент", "Введите номер опорного компонента:", ref op_component_name) == DialogResult.Cancel) return; if (!components_opor.ContainsKey(op_component_name)) { MessageBox.Show( "Опорный компонент " + op_component_name + " не пренадлежит выбранным блокам!", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly); return; } } Log.WriteLine(op_component_name + " - опорный компонент. Координаты:" + components_opor[op_component_name].x.ToString() + " " + components_opor[op_component_name].y.ToString()); var pcb = await OpenPcb(proj_name); double dx, dy; if (MessageBox.Show( "Переместить компоненты по образцу?", "Псевдо-блоки", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes) { Log.WriteLine("перемещение компонентов"); foreach (string key in components_opor.Keys) { if (key == op_component_name) continue; //Log.WriteLine(key + " - базовый компонент"); foreach (var bl in list_bl) { dx = components[bl + "-" + op_component_name].x - (components_opor[op_component_name].x - components_opor[key].x); dx = System.Math.Round(dx, 4); dy = components[bl + "-" + op_component_name].y - (components_opor[op_component_name].y - components_opor[key].y); dy = System.Math.Round(dy, 4); if (components.ContainsKey(bl + "-" + key)) { if (components[bl + "-" + key].x - dx > 0.05 || components[bl + "-" + key].y - dy > 0.05) { Log.WriteLine("перемещение компонента " + bl + "-" + key + " на " + dx.ToString() + " " + dy.ToString()); await pcb.RemoveComponent(bl + "-" + key); await pcb.PlaceComponent( designator: bl + "-" + key, mountSide: MountSide.Top, angle: components_opor[key].angle, location: new PointF((float)(dx), (float)(dy)) ); } } else { Log.WriteLine("создание компонента " + bl + "-" + key + " на " + dx.ToString() + " " + dy.ToString()); await pcb.PlaceComponent( designator: bl + "-" + key, mountSide: MountSide.Top, angle: components_opor[key].angle, location: new PointF((float)(dx), (float)(dy)) ); } } } } if (MessageBox.Show( "Расставить переходные отверстия?", "Псевдо-блоки", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes) { Log.WriteLine("создание переходных отверстий"); foreach (var via_op in ls_via_op) { dx = components_opor[op_component_name].x - via_op.x; dx = System.Math.Round(dx, 4); dy = components_opor[op_component_name].y - via_op.y; dy = System.Math.Round(dy, 4); foreach (var bl in list_bl) { await pcb.PlaceVia( location: new PointF((float)(components[bl + "-" + op_component_name].x - dx), (float)(components[bl + "-" + op_component_name].y - dy)), style: via_op.style, net: bl + "-" + via_op.net.Split('-')[1] ); } } } if (MessageBox.Show( "Произвести трассировку?", "Псевдо-блоки", MessageBoxButtons.YesNo, MessageBoxIcon.Information, MessageBoxDefaultButton.Button1, MessageBoxOptions.DefaultDesktopOnly) == DialogResult.Yes) { Log.WriteLine("создание трассировки"); foreach (var track_op in ls_tacks_op) { foreach (var bl in list_bl) { TrackSegment[] segment = {}; Array.Resize(ref segment, track_op.segments.Length); for(int i = 0; i < track_op.segments.Length; i++) { dx = components_opor[op_component_name].x - track_op.segments[i].x; dx = System.Math.Round(dx, 4); dy = components_opor[op_component_name].y - track_op.segments[i].y; dy = System.Math.Round(dy, 4); segment[i] = (new TrackSegment() { To = new PointF((float)(components[bl + "-" + op_component_name].x - dx), (float)(components[bl + "-" + op_component_name].y - dy)), Width = track_op.segments[i].w }); } dx = components_opor[op_component_name].x - track_op.x; dx = System.Math.Round(dx, 4); dy = components_opor[op_component_name].y - track_op.y; dy = System.Math.Round(dy, 4); await pcb.PlaceTrack( start: new PointF((float)(components[bl + "-" + op_component_name].x - dx), (float)(components[bl + "-" + op_component_name].y - dy)), segments: segment, net: bl + "-" + track_op.net.Split('-')[1], layer: track_op.layer ); } } } } } }