第一章 程 序 入 口
该程序开发的是一个AutoCAD动态连接库,下面是动态连接库的入口函数,在入口函数中用一个case语句对AutoCAD的两个消息进行响应,分别是AcRx::kInitAppMsg和kUnloadAppMsg,如下面的程序段所示
extern "C" AcRx::AppRetCode
acrxEntryPoint(AcRx::AppMsgCode msg, void* pkt)//动态连接库入口函数。
{
switch (msg) {
case AcRx::kInitAppMsg:
// Comment out the following line if your
// application should be locked into memory
acrxDynamicLinker->unlockApplication(pkt);
acrxDynamicLinker->registerAppMDIAware(pkt);
InitApplication();//初始化函数
break;
case AcRx::kUnloadAppMsg:
UnloadApplication();//卸载函数
break;
}
return AcRx::kRetOK;
}
1、初始化函数InitApplication()
下面是ARX向导为程序自动添加的代码段
void InitApplication()//初始化函数
{
//{ {AFX_ARX_INIT
AddCommand("GREEN", "DISPLAYWALL", "DISPLAYWALL", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NOINTERNALLOCK, greendisplaywall);
AddCommand("GREEN", "SCANROOM", "SCANROOM", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NOINTERNALLOCK, greenscanroom);
AddCommand("GREEN", "HIGHTLIGHT", "HIGHTLIGHT", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, greenhightlight);
AddCommand("GREEN", "HIGHLIGHTLINE", "HIGHLIGHTLINE", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, greenhighLightLine);
AddCommand("GREEN", "CREATDOEFILE", "CREATDOEFILE", ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET, greencreatdoefile);
//}}AFX_ARX_INIT
}
在该代码段中,注册用户开发的AutoCAD外部命令,在该代码段中共注册了SCANROOM 、DISPLAYWALL、HIGHTLIGHT以及HIGHLIGHTLINE,分别用于对工程图中的线条信息进行扫描、显示分析得到的墙体、以及进行房间线条的高亮显示和具体单个墙体的高亮显示。下面以SCANROOM为例对代码段中的注册外部命令的函数AddCommand()进行说明。
AddCommand("GREEN", //组名
"SCANROOM",//注册命令的外部名称
"SCANROOM", //注册命令的外部名称
ACRX_CMD_TRANSPARENT | ACRX_CMD_USEPICKSET | ACRX_CMD_NOINTERNALLOCK, //命令使用方式说明
Greenscanroom//命令执行时调用的函数模块
);
上面的命令SCANROOM执行时调用函数Greenscanroom(),在初始化中的另外几个命令分别调用函数greendisplaywall()、greenhightlight()和greenhighLightLine()。
Greenscanroom()函数用于对AutoCAD图中中的信息采用自顶向下的方法进行分析形成各种墙体信息,然后对墙体信息采用一种综合图论的支撑树算法和节点可见边有向排序算法的综合算法,对设计中的各个房间进行识别,关于自顶向下的方法形成墙体信息以及综合算法识别房间的详细介绍请参考论文,在笔者的论文中有详细的C伪代码,并且在本人的源代码段中都有详细的注释。下面分别对不同命令对应的函数进行介绍
1)SCANROOM命令执行时调用的函数Greenscanroom()
函数的代码如下:
void greenscanroom()
{
scanLines("wall",false);/*得到的信息保存在linehead中,linehead为一个全局变量,用于保存图纸信息。*/
refineLineSet();/*对获得的信息进行初步处理,对一些由于明显作图错误的问题进行处理*/
CLineSet *mid=new CLineSet();//*生成一个新的中心线集合,用于保持在分析中形成的中心线*/
CLineSet *midwall=new CLineSet();//生成一个集合,用于保存中间墙体的中心线。
make_whole_zone_mid(&linehead,mid,midwall);/*采用自顶向下的方法对墙体信息进行恢复*/
cut_middle_arc();//为一个空函数,预留用于对圆弧进行处理
displayMid(mid);//以墙体中心线为参数,在AutoCAD中显示中心线。
linehead.freeSet();///释放图纸信息
mid->freeSet();释放中心线占用的内存空间
}
这里要对函数中调用的make_whole_zone_mid()函数进行着重说明,在这个函数中,它的入口参数是lines,它是一个保存有图中线条信息的集合,在程序中对这个集合中的信息进行扫描,区分出墙区和中间墙区,对于墙区中的线条,采用凹陷点的办法识别中间的半墙,形成中心线条;对于中间墙区,生成两个方向的中心线,记录到入口参数midwall集合中
#define chendebug
void make_whole_zone_mid(CLineSet *lines,CLineSet *mid,CLineSet *midwall)
{
/*※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※
对整个图形中的线条lines先分墙区进行中心化,把墙区的中心线都加入到mid链表中,
对于中间墙体生成两条中心线,加入到midwall链表中
※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※※*/
CLineSet *head=NULL,*givenLine=NULL;//