5. PCB迭代程序
5.1 迭代程序的概念
迭代程序通过遍历印制板(PCB)编辑器数据库来查找印制板(PCB)对象,迭代程序被用于在数据库内,通过设置过滤选项,来查找具有指定属性的对象。印制板(PCB)编辑器支持两种类型的迭代程序,对象迭代程序和空间迭代程序。如果您选择了一种迭代程序类型,系统将自动地激活印制板(PCB)编辑器数据库,来选择一个适合的数据结构(平直的或空间的结构)。
迭代程序是一个强大的工具,使在印制板(PCB)文档中查找指定的印制板(PCB)对象,并且它有可能使用由程序开发者定义的查找标准来读取印制板(PCB)对象,实现此目的很简单,无需在您的数据库中创建一个相应的镜像数据结构,来查找印制板(PCB)对象。迭代程序是一个从印制板(PCB)编辑器的数据库中访问或修改或删除印制板(PCB)对象的紧密的方法。下面会有一些少量的例子,来说明如何适当的使用迭代程序。对象迭代程序,空间迭代程序将分别进行阐述。
5.2 对象迭代程序
5.2.1对象迭代程序函数
对象迭代程序用印制板句柄或组对象句柄遍历数据库,使用一组对象集合、迭代程序进程类型和定义的层来设立迭代程序机制。迭代函数需要使用下列API:
·PcbApi_CreateIterator
·PcbApi_DestroyIterator
·PcbApi_GetFirstObject
·PcbApi_GetNextObject
这四个迭代程序是设置查找和检索机制所必需的方法,每一个函数和它们的参数将被在其明细中说明,例子将说明如何使用迭代程序。
PCBApi_CreateIterator
|
参数 |
描述 |
|
AParentObject |
这是一个查找对象的句柄(一个印制板对象或一个元件对象)。 |
|
ObjectKind |
ObjectKind参数表示查找机制要基于的对象种类。 |
|
AMethod |
迭代程序进程的类型。 |
|
Alayer |
查找机制要基于的层。 |
PCBApi_CreateIterator返回对象迭代程序的句柄,为了遍历所有的层,使用一个外循环是必需的,这样每一层能被读取到PCBApi_CreateIterator函数中,对象查找方法,eProcessAll类型查找所有PCB对象类型,eProcessFree类型查找自由PCB对象或者仅图元,eProcessComponent类型仅查找内置元件对象。
PCBApi_DestroyIterator
|
参数 |
描述 |
|
Iterator |
一个迭代程序的句柄。 |
PcbApi_DestroyIterator函数用于查找进程结束时销毁迭代程序对象。
PcbApi_GetFirstObject
|
参数 |
描述 |
|
Iterator |
一个迭代程序的句柄。 |
PcbAPI_GetFirstObject返回第一个查找到的印制板(PCB)对象的句柄。
PcbApi_GetNextObject
|
参数 |
描述 |
|
Iterator |
一个迭代程序的句柄。 |
PcbAPI_GetNextObject返回下一个查找到的印制板(PCB)对象的句柄。
此进程使用基于While Do的对象迭代程序来查找指定的PCB对象,也就是说,循环体直到查找到PCB对象的句柄是零为止。
通过PcbApi_GetCurrentBoardHandle函数获得当前的印制板句柄。
PcbApi_CreateIterator函数通过使用支持的参数、父类句柄、对象类型、进程方法和层来获得迭代程序的句柄。
用PcbApi_GetFirstObject函数取得第一个查找到的PCB对象的句柄并且接着做一些处理,不要忘记对此PCB对象调用QueryDatabase(eGetState)和QueryDatabase(eSetState) 。使用PcbApi_GetNextObject函数继续调用对象句柄并且做处理。
一旦对象句柄为零,也就是说,这里没有更多的查找到的对象,接着使用PcbApi_DestroyIterator函数来销毁此迭代程序。
5.2.2对象迭代程序例子
·例子1,统计焊盘数量
请见SDK例子\SAMPLES\NO4\API\PCB\CountPads。
{....................................................................................}
//此代码例子遍历PCB编辑器数据库来统计焊盘(pad)对象,报告在PCB文档中查找到的焊盘(pad)数量。
Procedure RunIteratorExample;
Var
BoardHandle: TObjectHandle;
PadHandle: TObjectHandle;
IteratorHandle : TObjectHandle;
PadNumber: Integer;
Begin
PadNumber := 0;
BoardHandle := PcbApi_GetCurrentBoardHandle;
//PcbApi_GetCurrentBoardHandle函数返回当前在设计资源管理器中的PCB文档的句柄,如果印制板没有找到,则返回值是空(nil)。
IteratorHandle:= PcbApi_CreateIterator(BoardHandle, ePadObject,
eProcessAll, eIgnoreLayer);
//PcbApi_CreateIterator函数返回到一个迭代程序对象的对象句柄。
PadHandle := PcbApi_GetFirstObject(IteratorHandle);
// PcbApi_GetFirstObject函数使用给定的迭代程序(iterator)句柄返回第一个发现的PCB对象句柄。此函数在PcbApi_CreateIterator函数后和PcbApi_GetNextObject函数被使用前被立即调用。
While(PadHandle <> 0) Do
Begin
PadNumber := PadNumber + 1;
//计数查找到的焊盘数量。
PadHandle := PcbApi_GetNextObject(IteratorHandle);
//PcbApi_GetNextObject函数使用给定的迭代程序句柄返回下一个查找到的PCB对象的句柄。
End;
PcbApi_DestroyIterator(IteratorHandle);
//销毁此迭代程序对象。
ShowInfo('焊盘总数(Pad Count) = ' + IntToStr(PadNumber));
//显示焊盘数量。
End;
此段代码使用了下列重要的函数或过程。
|
PcbApi_GetCurrentBoardHandle |
PcbApi_CreateIterator |
PcbApi_DestroyIterator |
|
PcbApi_GetFirstObject |
PcbApi_GetNextObject |
这段代码做什么?
PcbApi_CreateIterator使用当前印制板的句柄、焊盘种类(ePadObject)、eProcessAll和eIgnoreLaye参数创建迭代程序对象,在迭代程序循环前,PcbApi_GetFirstObject函数使用迭代程序对象句柄来查找到第一个焊盘对象。PcbApi_GetNextObject方法被调用直到没有更多的焊盘对象句柄被查找到为止,一旦没有更多的焊盘对象被查找到,PcbApi_DestroyIterator被调用来销毁迭代程序对象。
·例子2,统计每一个元件对象中的线对象
请见SDK例子\SAMPLES\NO4\API\PCB\Count Tracks of a Component。
{....................................................................................}
//此例子示范统计一个PCB文档中的一个组对象中内嵌的对象的方法,在此例子中,每一个元件对象(Component)的线(Tracks)被统计。
Procedure ObjectIteratorExample;
Var
TrackHandle : TObjectHandle;
TrackIteratorHandle : TObjectHandle;
ComponentHandle : TObjectHandle;
ComponentIteratorHandle : TObjectHandle;
Track : TPCBTrack;
TrackCount: Integer;
Component : TPCBComponent;
Begin
If PcbApi_GetCurrentBoardHandle = 0 Then Exit;
//如果当前激活的编辑器不是PCB编辑器则退出。
Component := TPCBComponent.Create(0);
//创建一个元件对象。
Track := TPCBTrack.Create(0);
//创建一个线对象。
TrackCount := 0;
//线总数先置为0。
ComponentIteratorHandle := PcbApi_CreateIterator(PcbApi_GetCurrentBoardHandle,
eComponentObject,//元件对象
eProcessAll,//处理所有
eIgnoreLayer);
//PcbApi_CreateIterator函数返回到一个迭代程序对象的对象句柄。
ComponentHandle := PcbApi_GetFirstObject(ComponentIteratorHandle);
// PcbApi_GetFirstObject函数使用给定的迭代程序(iterator)句柄返回第一个发现的PCB对象句柄。
While(ComponentHandle <> 0) Do //查找元件对象
Begin
Component.Objecthandle := Componenthandle;
//把查找的元件对象句柄赋予元件的对象句柄属性。
Component.QueryDatabase(eGetstate);
//用内部服务器数据同步外部服务器数据。
TrackIteratorHandle := PcbApi_CreateIterator(Component.Objecthandle,//元件对象。
eTrackObject,//线对象。
eProcessAll,//处理所有。
eTopOverlay);
//基于查找到的元件对象建立查找其内部线对象的迭代程序。
TrackHandle := PcbApi_GetFirstObject(TrackIteratorHandle);
//查找第一个线对象。
While(TrackHandle <> 0) Do //如果找到线对象。
Begin
Inc(TrackCount);//线对象计数。
TrackHandle := PcbApi_GetNextObject(TrackIteratorHandle);
//查找下一个线对象,在内循环中。
End;
If Not ConfirmNoYes('此元件(This Component) ' + Component.Pattern + ' 有(has) ' +
IntToStr(TrackCount)+ ' 线(Tracks)。' + #13 + #13 + '继续(Continue) ?') Then Break;
//提示用户当前查找到的元件有多少线对象并询问是否继续,如果不则中断。
TrackCount := 0;//线对象总数置空。
PcbApi_DestroyIterator(TrackIteratorHandle);//销毁线查找迭代程序
ComponentHandle := PcbApi_GetNextObject(ComponentIteratorHandle);
//查找下一个元件对象,在外循环中。
End;
PcbApi_DestroyIterator(ComponentIteratorHandle);
//销毁元件查找迭代程序。
Track.Free;//线对象释放。
Component.Free;//组件对象释放。
End;
这段代码做什么?
这里有两个循环,外循环在印制板数据库中查找元件对象,内循环在元件对象中查找线对象,迭代程序在元件(Component)对象内寻找线对象并且报告在每一个元件对象中查找到的线对象的总数。
5.3 空间迭代程序
空间迭代程序通过边界约束、层设置和对象种类集合来遍历印制板(PCB)编辑器数据库,参数有 (X1,X2,Y1,Y2)、层设置、被提供的对象类型集合。
5.3.1空间迭代程序函数
空间迭代程序函数是使用印制板句柄或组对象句柄、定义的区域、层设置和对象种类设置三个参数,来遍历数据库的迭代程序函数,当使用空间迭代程序时,内置在PCB编辑器中的数据库自动使用空间数据结构。
为建立迭代程序机制,需要使用下列的迭代程序API函数。
·PcbApi_CreateSpatialIterator
·PcbApi_DestroySpatialIterator
·PcbApi_GetNextSpatialObject
·PcbApi_GetFirstSpatialObject
这四个空间迭代程序是设置查找和检索机制的必需的方法,每一个函数和它们的参数将在其明细中被说明,例子说明了如何使用空间迭代程序。
PcbApi_CreateSpatialIterator
|
参数 |
描述 |
|
AparentObject |
AparentObject定义一个空间迭代机制将基于的容器。 |
|
X1,Y1,X2,Y2X1,Y1,X2,Y2 |
定义一个空间迭代机制将基于的区域。 |
|
SearchLayerSet |
SearchLayerSet定义了一个空间迭代机制将基于的一组层。 |
|
BoardPrimitiveSet |
BoardPrimitiveSet定义了一个空间迭代机制将基于的一组对象。 |
PcbApi_CreateSpatialIterator返回迭代程序对象的句柄,为了遍历一个选择的层组,您需要为SearchLayerSet参数来定义层的集合,为处理一个确定的图元组,您需要来定义BoardPrimitiveSet。
PcbApi_DestroySpatialObject
|
参数 |
描述 |
|
Iterator |
表示要销毁迭代程序的句柄。 |
PcbApi_DestroySpatialIterator被用在查找进程结束时销毁迭代程序对象。
PcbApi_GetFirstSpatialObject
|
参数 |
描述 |
|
Iterator |
一个迭代程序的句柄。 |
|
ObjectKind |
为迭代程序进程返回或设置对象的种类。 |
PcbAPI_GetFirstSpatialObject设立一个迭代程序并且返回第一个查找到的对象句柄。
PcbApi_GetNextSpatialObject
|
参数 |
描述 |
|
Iterator |
一个迭代程序的句柄。 |
|
ObjectKind |
为迭代程序进程返回或设置对象的种类。 |
PcbAPI_GetNextSpatialObject返回下一个查找到的对象句柄。
此进程使用基于While Do的空间迭代程序来查找指定的PCB对象,也就是说,循环体直到查找到PCB对象的句柄是零为止。
通过PcbApi_GetCurrentBoardHandle函数获得当前的印制板句柄。
PcbApi_CreateSpatialIterator函数通过使用其所支持的参数、父类句柄、对象类型、进程方法和层来创建空间迭代程序的句柄。
使用PcbApi_GetFirstSpatialObject函数得到第一个查找到的对象的句柄,使用PcbApi_GetNextSpatialObject函数继续查找,得到下一个查找到的一个对象的句柄。
用PcbApi_GetFirstSpatialObject函数取得第一个查找到的PCB对象的句柄,并且接着做一些处理,不要忘记对此PCB对象调用QueryDatabase(eGetState)和QueryDatabase(eSetState) ,再使用PcbApi_GetNextSpatialObject函数继续调用对象句柄来进行下一个对象的查找并且做处理。
一旦查找到的对象句柄为零,也就是说,再也没有更多的对象被查找到,最后使用PcbApi_DestroySpatialIterator函数来销毁此迭代程序对象。
5.3.2空间迭代程序例子
请见SDK例子\SAMPLES\NO4\API\PCB\SearchAndHighLightFreePrims。
此代码例子查找并且在边界约束内高亮查找到的对象。
{....................................................................................}
Procedure UpdateDisplay;
Var
P : PChar;
Begin
GetMem(P, 255);//创建一个动态的内存变量并且指针到内存块的地址,大小为255。
StrPCopy(P,'');//复制一个空字符到一个空值终止的字符串,即用空值初始化内存块。
SetState_Parameter(P,'Action','All');
//SetState_Parameter过程插入一个参数到指定的参数文本块中,为动作,参数为All。
MessageRouter_SendCommandToModule('PCB:Zoom',P,255,0);
//MessageRouter_SendCommandToModule函数运行指定的过程在指定的模块内,如果成功则返回True,否则返回Flase.此函数允许一个服务器来运行一个在其它服务器中的进程。即调用PCB服务器中的Zoom缩放进程。
FreeMem(P,255);//释放变量
End;
{....................................................................................}
Procedure SearchForObjectsWithinTheBoundaryRectangle;
Var
BoardHandle: TObjectHandle;
PCBObject: TPCBObject;
Iterator: TObjectHandle;
X1,Y1,X2,Y2: Tcoord;
ASetOfLayers: TSetOfLayers;
ASetOfObjects : TSetOfObjects;
ObjectKind: TObjectID;
ObjectHandle: TObjecthandle;
Begin
BoardHandle := PcbApi_GetCurrentBoardHandle;
//PcbApi_GetCurrentBoardHandle函数返回当前在设计资源管理器中的PCB文档的句柄,
//如果印制板没有找到则返回值是空(nil)。
If BoardHandle = 0 Then //当前激活文档并非是PCB文档则退出
Begin
ShowMessage('在客户端中没有PCB文档当前被打开。(No PCB document is currently open in Client.)');
Exit;
End;
If Not (PcbApi_ChooseRectangleByCorners(BoardHandle,
'请选择第一个角(Choose first corner)',
'请选择第二个角(Choose final corner)',
x1,y1,x2,y2)) Then Exit;
//通过用户光标选择第一个角和第二外角来确定一个区域,PcbApi_ChooseRectangleByCorners
//函数提示用户来在印制板上两次点击来返回一个矩形的坐标。
//为空间迭代程序设置定义。
ASetOfLayers:= [eTopLayer,eBottomLayer];//设置层,eTopLayer、eBottomLayer。
ASetOfObjects := [eArcObject,eTrackObject];//设置要查找的对象,弧对象、线对象。
Iterator := PcbApi_CreateSpatialIterator(BoardHandle,//当前印制板句柄。
X1,Y1,X2,Y2,//边界坐标。
ASetOfLayers,//查找基于的层。
ASetOfObjects);//要查找到的对象。
//创建一个空间迭代程序。
//空间迭代程序在一个循环中。
ShowInfo('这里将高亮显示查找到的对象(getting there)...');
For ObjectKind := eArcObject To eTrackObject Do //外循环控制要查找的对象集合。
Begin
ObjectHandle := PcbApi_GetFirstSpatialObject(Iterator, ObjectKind);
//PcbApi_GetFirstSpatialObject函数使用给定的空间迭代程序句柄来返回第一个查找到的对象的句柄。
While ObjectHandle <> 0 Do //查找直到找不到为止。
Begin
PCBObject := TPCBObject.Create(0);//新建立PCB对象。
PCBOBject.ObjectHandle := ObjectHandle;//把查找到的对象句柄赋予新建的PCB对象。
PCBObject.QueryDataBase(eGetState);
//用内部服务器数据同步外部服务器数据,即把查找到的PCB对象中数据赋予新建的PCB对象。
PCBObject.SetState_Selection(True);//设置PCB对象的选择状态。
PCBObject.QueryDataBase(eSetState);//内外部服务器数据同步内部服务器数据。
PCBObject.Free;//新建的PCB对象释放。
ObjectHandle := PcbApi_GetNextSpatialObject(Iterator, ObjectKind);
//PcbApi_GetNextSpatialObject函数使用给定的空间迭代程序句柄返回下一个查找
//到的对象句柄连同对象种类值。
End;
End;
PcbApi_DestroySpatialIterator(Iterator);
//销毁空间迭代程序。
UpdateDisplay;//更新显示。
End;
此段代码使用了下列重要的函数或过程。
|
PcbApi_CreateSpatialIterator |
PcbApi_GetCurrentBoardHandle |
|
PcbApi_GetFirstSpatialObject |
QueryDatabase |
|
PcbApi_GetNextSpatialObject |
PcbApi_DestroySpatialIterator |
这段代码做什么?
如果需要此代码能有效地工作,您需要在设计资源管理器99中打开一个PCB文档,使用函数PcbApi_ChooseRectangleByCorners来为此空间迭代程序对象选取一个边界矩形的坐标,在PCB文档上使用一个边界矩形,是为了让空间迭代程序在此区域中查找对象,一旦弧对象和线对象被在此边界矩形内查找到,它们的选择属性被激活,这些对象将被高亮显示。(e-works)