Skip to main content
View as Markdown

Working with PCBs

The current board​

IPCB_ServerInterface.GetCurrentPCBBoard returns the board of the document in the current view, or null when there is no current view or the current view is not a PCB document. A board is an IPCB_Board:

IPCB_ServerInterface pcbServer = PCB.GlobalVars.PCBServer;
IPCB_Board board = pcbServer?.GetCurrentPCBBoard();
if (board == null)
return;

IPCB_ServerInterface.GetPCBBoardByPath returns the board of an open PCB document by its file name, or null when no open PCB document has that file name.

Coordinates​

Coordinates and sizes are int values in internal units: 10,000 per mil (EDP.EDPConstant.InternalUnits). EDP.Utils converts them: EDP.Utils.MilsToCoord and EDP.Utils.MMsToCoord to internal units, EDP.Utils.CoordToMils and EDP.Utils.CoordToMMs back.

int width = EDP.Utils.MilsToCoord(10); // 100000
double mm = EDP.Utils.CoordToMMs(width); // 0.254

Object locations are absolute. The origin that the PCB editor shows is IPCB_Board.XOrigin, IPCB_Board.YOrigin: subtract it to get a location relative to that origin, and add it to place an object relative to it.

int x = board.GetState_XOrigin() + EDP.Utils.MilsToCoord(500);

Iterating over objects​

Iterators walk the objects of a board or of a group object. Each kind is created and destroyed by its owner:

Set the filters of the IPCB_AbstractIterator, then step through the objects with IPCB_AbstractIterator.FirstPCBObject and IPCB_AbstractIterator.NextPCBObject, which return null after the last object:

IPCB_BoardIterator iterator = board.BoardIterator_Create();
iterator.AddFilter_ObjectSet(new PCB.TObjectSet { TObjectId.eTrackObject });
iterator.AddFilter_LayerSet(new TV6_LayerSet { TV6_Layer.eV6_TopLayer });

for (var track = iterator.FirstPCBObject() as IPCB_Track; track != null; track = iterator.NextPCBObject() as IPCB_Track)
{
// ...
}

board.BoardIterator_Destroy(ref iterator);

The destroy methods take the iterator by ref: they free it and set the variable to null.

IPCB_AbstractIterator.AddFilter_Area restricts a spatial iterator to a rectangle; the corners can be given in any order. It does not restrict a board iterator: use a spatial iterator for an area.

Changing objects​

Bracket changes to a board with IPCB_ServerInterface.PreProcess and IPCB_ServerInterface.PostProcess, and each changed object with IPCB_Primitive.BeginModify and IPCB_Primitive.EndModify:

pcbServer.PreProcess();

track.BeginModify();
track.SetState_Width(EDP.Utils.MilsToCoord(10));
track.EndModify();

pcbServer.PostProcess();

New objects come from IPCB_ServerInterface.PCBObjectFactory; set their properties, then add them with IPCB_Board.AddPCBObject:

pcbServer.PreProcess();

var via = pcbServer.PCBObjectFactory(TObjectId.eViaObject, TDimensionKind.eNoDimension, TObjectCreationMode.eCreate_Default) as IPCB_Via;
via.SetState_XLocation(board.GetState_XOrigin() + EDP.Utils.MilsToCoord(500));
via.SetState_YLocation(board.GetState_YOrigin() + EDP.Utils.MilsToCoord(500));
via.SetState_Size(EDP.Utils.MilsToCoord(50));
via.SetState_HoleSize(EDP.Utils.MilsToCoord(20));
board.AddPCBObject(via);

pcbServer.PostProcess();

Redrawing​

IPCB_Primitive.GraphicallyInvalidate redraws one object; it does nothing for the board itself or for an object that has no board. IPCB_Board.ViewManager_GraphicallyInvalidatePrimitive does the same through the board, and IPCB_Board.ViewManager_FullUpdate redraws the whole board.

Layers​

Layers have two .NET representations:

  • TV6_Layer, an enumeration with a fixed set of layers (for example 30 mid layers and 16 mechanical layers), and its set TV6_LayerSet, used by the iterator filters.
  • V7_LayerBase and V7_Layer, which derives from it, a layer value that can identify every layer. Create one from a TV6_Layer with new V7_Layer(TV6_Layer.eV6_TopLayer).

IPCB_Primitive.Layer is a TV6_Layer: an object on a layer outside that fixed set reads as the nearest value (for example TV6_Layer.eV6_Mechanical16 for every mechanical layer above 16). IPCB_Primitive.V7Layer is the exact layer.

V7_LayerBase layer = track.GetState_V7Layer();
track.SetState_V7Layer(new V7_Layer(TV6_Layer.eV6_BottomLayer));

Boards without a view​

Members that work on the board's view need the board to be open in a PCB editor view. Without one, IPCB_Board.ChooseLocation and IPCB_Board.ChooseRectangleByCorners return false without prompting, IPCB_Board.GetObjectAtCursor returns null, IPCB_Board.XCursor, IPCB_Board.YCursor and IPCB_Board.Window read 0, and setting IPCB_Board.CurrentLayerV7 or IPCB_Board.LayerIsDisplayed has no effect. Each member's page says what it does without a view.

Objects that no longer exist​

An interface reference such as an IPCB_Track stays usable only while the object it stands for exists. Once that object has been destroyed, every call through the reference fails with the error "Object accessed after being destroyed".