Современная электроника №4/2020
ПРОЕКТИРОВАНИЕ И МОДЕЛИРОВАНИЕ 68 WWW.SOEL.RU СОВРЕМЕННАЯ ЭЛЕКТРОНИКА ◆ № 4 2020 Palette, в которой есть стандартные визу- альные WindowsForms-примитивы для отображения в окне программы. Все объ- екты, вставленные в форму в редакторе кода, можно обрабатывать ипо различ- нымдействиямна объектыпроизводить определённыйнаборнеобходимых дей- ствий. После завершения написания скрипта команду его запускаможно вне- дрить во вновь созданнуюстрочку меню или кнопку в панелиинструментов, для этого в менюEdit Command редактиро- вания кнопки необходимо вставить: Process : ScriptingSystem:RunScript Parameters : ProjectName=[имя проекта]|ProcName=[файл кода]. pas>[имя метода] Примеры реализации скрипта В качестве примера приводится код скрипта на языке Delphi с использо- ванием API и на языке С# – с исполь- зованием SDK. Программа выполняет поиск переходных отверстий на плате, координаты которых не кратны теку- щей координатной сетке, и накладыва- ет на такие отверстия маску, тем самым скрывая все остальные примитивы плат. Результат выполнения скрипта представлен на рисунке 3. Следующий пример создан на языке Delphi. Его можно повторить, исполь- зуя API: создать файл viagrid.pas, внеся в него следующий код, и вызвать через меню File – Run Script: (см. Листинг 1). Пример реализации этой же про- граммы на языке С# с использовани- ем SDK приведён в Листинге 2. Оба приведённых примера доступны для общего пользования в публичном репозитории по адресу https://github. com/glavkondev. Заключение Открытые средства для разработ- ки прикладных программ для Altium Desinger позволяют решать любые, возникающие у пользователей подза- дачи. В руках программистов данные средства могут значительно увеличить эффективность работы с системой про- ектирования для рядовых пользовате- лей. Скрипты и плагины могут быть раз- личной сложности: от обычного вывода справочной информации до сложных интеграционных систем, позволяю- щих обеспечить связь Altium Designer с другими внедрёнными на предприя- тии системами. За всю историю развития Altium Designer инженерами-энтузиастами было написано множество приклад- ных программ и скриптов, решаю- Рис. 3. Результат выполнения примера скрипта щих конкретные узконаправленные задачи. Множество из них находится в открытом доступе [3], их можно уста- новить, модифицировать и использо- вать для решения любых возникаю- щих задач. Литература 1. Документация Altium DXP Developer. URL: https://www.altium.com/ru/ documentation/ altium-dxp-developer. 2. Документация по Altium Designer API. URL: https://techdocs.altium.com/display/ SCRT/Altium+Designer+API+Reference. 3. Сборник скриптов для Altium Designer. URL: https://github.com/Altium-Designer- addons/scripts-libraries. Листинг 1 function viagrid; var Board : IPCB_Board; Iter : IPCB_BoardIterator; Via : IPCB_Via; grid, x, y : double; begin Board := PCBServer.GetCurrentPCBBoard; If Board = Nil then exit; ResetParameters; AddStringParameter('Scope','All'); RunProcess('PCB:DeSelect'); Iter := Board.BoardIterator_Create; Iter.AddFilter_ObjectSet(MkSet(eViaObject)); Iter.AddFilter_AllLayers; Via := Iter.FirstPCBObject; While (Via <> nil) do begin x := roundto(coordtomms(Via.x-Board.BoardOutline.BoundingRectangle. Left),-3); y := roundto(coordtomms(Via.y-Board.BoardOutline.BoundingRectangle. Bottom),-3); grid := roundto(coordtomms(Board.ComponentGridSize),-3); if ((frac(x / grid) <> 0) or (frac(y / grid) <> 0)) then Via.Selected := True; Via := Iter.NextPCBObject; end; Board.BoardIterator_Destroy(Iter); Client.PostMessage('PCB:RunQuery','Apply=True|Expr=IsSelected|Mask=T rue', Length('Apply=True|Expr=IsSelected|Mask=True'), Client.CurrentView); end; Листинг 2 public void Command_Viagrid(IServerDocumentView view, ref string parameters) { IPCB_ServerInterface pcbServer = PCB.GlobalVars.PCBServer; if (pcbServer == null) return; IPCB_Board pcbBoard = pcbServer.GetCurrentPCBBoard(); if (pcbBoard == null) return; DXP.Utils.RunCommand("PCB:DeSelect", "Scope=All"); var boundingRect = pcbBoard.GetState_BoardOutline(). BoundingRectangle(); var gridSize = (int)pcbBoard.GetState_ComponentGridSize(); var delta = EDP.Utils.MMsToCoord(0.001); IPCB_BoardIterator iterator = pcbBoard.BoardIterator_Create(); iterator.AddFilter_ObjectSet(new PCB.TObjectSet(PCB.TObjectId. eViaObject)); iterator.AddFilter_LayerSet(PCBConstant.V6AllLayersSet); iterator.AddFilter_Area(boundingRect.Left, boundingRect.Bottom, boundingRect.Right, boundingRect.Top); IPCB_Primitive pcbObject = iterator.FirstPCBObject(); while (pcbObject != null) { if (pcbObject is IPCB_Via via && (via.GetState_XLocation() % gridSize > delta || via.GetState_XLocation() % gridSize > delta)) via.SetState_Selected(true); pcbObject = iterator.NextPCBObject(); } pcbBoard.BoardIterator_Destroy(ref iterator); DXP.Utils.RunCommand("PCB:RunQuery", "Apply=True|Expr=IsSelected|Mask=True|Select=True"); }
RkJQdWJsaXNoZXIy MTQ4NjUy