⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 annolink.mc

📁 Bentley Microstation的二次开发工具MDL的学习源代码
💻 MC
字号:
/*================================================================================
						Step by step 之 MDL 快速入门实例十四
================================================================================*/
#include    <mselems.h>
#include    <dbdefs.h>
#include    <dberrs.h>
#include    <string.h>
#include    <mdl.h>
#include    <scanner.h>
#include    <basetype.h>
#include    <rdbmslib.fdf>
#include    <mslinkge.fdf>
#include    <mslstyle.h>
#include    <dlogitem.h>            
#include    <cexpr.h>	           
#include    <userfnc.h>
#include    <cmdlist.h>	            
#include    <colrname.h>
#include    <stdarg.h>
#include    <dlogids.h>
#include    <dlogitem.h>
#include    <stdlib.h>
#include    <stdio.h>
#include    <tcb.h>
#include    <dlogman.fdf>           
#include    <mselemen.fdf>

int COLOR_HEIGHTPOINT=6;
int LEVEL_HEIGHTPOINT=8;
int COLOR_HEIGHTTEXT=2;
int LEVEL_HEIGHTTEXT=14;

typedef struct tagAnnotationLinkage{
	ULong fpos1, fpos2;
}AnnotationLink;

AnnotationLink annolink[2000];

void GetFirstPoint(MSElementDescr *emd, Dpoint3d *dp);

int annocount=0;
double TOLERANCE=0.2;
double SCALE=500;

int annoLink_save(ULong fp1, ULong fp2)
{
	if (annocount>=2000-1) 
	{
		mdlDialog_openInfoBox("图中关联注记太多,超出程序处理能力!");
		return FALSE;
	}

	annolink[annocount].fpos1=fp1;
	annolink[annocount++].fpos2=fp2;             //记数用annocount
	return TRUE;
}


int annoLink_findFirst(ULong fp)
{
	int i;
	
	for (i=0; i<annocount; i++)
		if (annolink[i].fpos1==fp || annolink[i].fpos2==fp) return i+1;   //id号从1开始,是人为地添加的,保存高程点及文本注记在数组annolink[2000]中以0开始
	return -1;
}

int annoLink_findNext(ULong fp, int cur)    //一个文本值关联二个高程点的情况 文本值的位置fp是一样的,而高程点的位置不一样,所以要用"||"
{
	int i;
	
	for (i=cur+1; i<annocount; i++)
		if (annolink[i].fpos1==fp || annolink[i].fpos2==fp) return i+1;
	return -1;
}


//添加注记关联linkage
void sdElmdscr_saveID(MSElementDescr *elmDP, ULong id)
{
	ULong data[2];
	data[0]=0x00991003;
	data[1]=id;
	mdlElement_appendAttributes(&elmDP->el, 4, (short *)data);
}   


// 写日志文件
void Create_log_File(FILE *fpCoord, double Height_Pointx, double Height_Pointy, int errtype)
{		
	fprintf(fpCoord,"%5d %19.6lf %19.6lf\n",errtype,Height_Pointx,Height_Pointy);
}


// 在指定坐标周围寻找文本注记
// 返回找到的数量和第一个的位置
int FindElement(double Height_Pointx, double Height_Pointy, ULong *pos)
{
	int i,number,mScanWords,mStatus,mElmNum;
	Scanlist mScanList;
	ULong mNextFilePos,mRetPos[100],mActualPos;
	MSElementDescr  *elmDP;
	Dpoint3d dpoint;
	int color,level,type;
	double range;

	// Scan all text elements in range
	mdlScan_initScanlist(&mScanList);
	mScanList.scantype = ELEMTYPE|NESTCELL;
	mScanList.extendedType=FILEPOS;
	mdlScan_noRangeCheck(&mScanList);

	range=TOLERANCE*SCALE;	// 搜索矩形半宽
	mdlCnv_masterToUOR(&(range), range, MASTERFILE);
	dpoint.x=Height_Pointx-range; dpoint.y=Height_Pointy-range; dpoint.z=0;
	mScanList.xlowlim=mdlCnv_toScanFormat(dpoint.x);	// scan range
	mScanList.ylowlim=mdlCnv_toScanFormat(dpoint.y);

	dpoint.x=Height_Pointx+range; dpoint.y=Height_Pointy+range; dpoint.z=0;
	mScanList.xhighlim=mdlCnv_toScanFormat(dpoint.x);
	mScanList.yhighlim=mdlCnv_toScanFormat(dpoint.y);

	mdlScan_setDrawnElements(&mScanList);


	mdlScan_initialize(0, &mScanList);
        number=0;
	do{
		mScanWords=sizeof(mRetPos)/sizeof(UShort);                                         
		mStatus=mdlScan_file(mRetPos, &mScanWords, sizeof(mRetPos), &mNextFilePos);
		mElmNum=mScanWords/sizeof(UShort);
		for(i=0;i<mElmNum;i++)                 /* The circulation manipulate all points that accord with condition */
			{
			mdlElmdscr_read(&elmDP,mRetPos[i],0,0,&mActualPos);
			type=elmDP->el.hdr.ehdr.type;
		    if (type!=8 && type!=9 && type!=10 && type!=66 && type!=5) 
			    {
					if (elmDP->h.firstElem!=NULL)
					{
						level=elmDP->h.firstElem->el.ehdr.level;
						mdlElement_getSymbology(&color,NULL,NULL,&elmDP->h.firstElem->el);
					}
					else
					{
						mdlElement_getProperties(&level,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&elmDP->el);
						mdlElement_getSymbology(&color,NULL,NULL,&elmDP->el);
					}
			     }
	                if(color==COLOR_HEIGHTTEXT && level==LEVEL_HEIGHTTEXT)
		                {
		                number=number+1;
		                if(number==1) *pos=mRetPos[i];
		                }
			mdlElmdscr_freeAll(&elmDP);
			}
	}while(mStatus==BUFF_FULL);

	return number;
}


int process(char *fntag, char *fnlog)
{
	FILE   	*ftag, *flog;
	ULong  	filepos, nextpos, topos;
	MSElementDescr  *emd;
	int  	color, level, type, count;
	double 	Height_Pointx, Height_Pointy;
	int 	id;
	char 	fname[256], *tmp, str[256];
	char    path[256],newpath[256];
	char	*pname,*newpname;
	char    Text_string[100];
	Dpoint3d dp;

	int i,mScanWords,mStatus,mElmNum;
	Scanlist mScanList;
	ULong mNextFilePos,mRetPos[100],mActualPos,pos1;
	MSElementDescr  *elmDP;
	double text_Pointx,text_Pointy;

	flog=fopen(fnlog,"w+");	// 创建日志文件
	if (!flog) return FALSE;

	// search for possible annotation links
	annocount=0;
	filepos=0;
	while(nextpos=mdlElmdscr_read(&emd,filepos,0,0,&filepos))   
        {
 		type=emd->el.hdr.ehdr.type;
		if (type!=8 && type!=9 && type!=10 && type!=66 && type!=5) 
		{
			if (emd->h.firstElem!=NULL)
			{
				level=emd->h.firstElem->el.ehdr.level;
				mdlElement_getSymbology(&color,NULL,NULL,&emd->h.firstElem->el);
			}
			else
			{
				mdlElement_getProperties(&level,NULL,NULL,NULL,NULL,NULL,NULL,NULL,&emd->el);
				mdlElement_getSymbology(&color,NULL,NULL,&emd->el);
			}
			if(color==COLOR_HEIGHTPOINT && level==LEVEL_HEIGHTPOINT)	// 是高程点
		        {
		        	GetFirstPoint(emd, &dp);
			        Height_Pointx=dp.x;
			        Height_Pointy=dp.y;
	        	
					count=FindElement(Height_Pointx, Height_Pointy, &topos);        //参数同时变化!!!!!!

			        if(count==1)	// 正好一一对应,匹配成功
						{
						if (annoLink_save(filepos, topos)==FALSE) break;	// 缓冲区已满,不必再找。 分别是高程点,高程文本之文件位置
				        }
			        else		    // 否则记入日志文件
				        {
						mdlCnv_UORToMaster(&(Height_Pointx), Height_Pointx, MASTERFILE);
						mdlCnv_UORToMaster(&(Height_Pointy), Height_Pointy, MASTERFILE);
		                Create_log_File(flog, Height_Pointx, Height_Pointy, count);
						}
				}
		}
		filepos=nextpos;
        mdlElmdscr_freeAll(&emd);
	}


	fclose(flog);
	ftag=fopen(fntag, "wb+");

	if (!ftag) return FALSE;
	
	// create new design with annotation linkage
	filepos=0;
	while(nextpos=mdlElmdscr_read(&emd,filepos,0,0,&filepos))   
        {
		/*+++++++++++++++++++++++++++++++++++++++++++++++
		这里也有错误:
		1.找的时候是把高程点的filepos存成fpos1,注记文本的filepos为fpos2,
		    所以找的时候不能混用;
		2.添加linkage时对高程点和高程注记是不同的linkage来添加;
		3.上面的存储方式不可能出现一个高程点对应几个高程信息的情况,所以
            在查找的时候只要遍历存下的高程点的filepos就行了
		------------------------------------------------*/
		id=annoLink_findFirst(filepos);
		while (id>0)
		{
			sdElmdscr_saveID(emd,id);
			id=annoLink_findNext(filepos,id);
		}
		mdlWorkDgn_write(emd,-1,ftag,0,0);
		filepos=nextpos;
		mdlElmdscr_freeAll(&emd);
	}
	fclose(ftag);
	return TRUE;
}


void main (int argc,char *argv[])
{
	char   	filename[256],filename1[256];
	char 	fname[256], *tmp, str[256];
	char    path[256],newpath[256];
	char	*pname,*newpname;
	FindFileInfo	*fileInfoP;
	int	fileCount;

	if (argc>2) sscanf(argv[2], "%d", &LEVEL_HEIGHTPOINT);
	if (argc>3) sscanf(argv[3], "%d", &COLOR_HEIGHTPOINT);
	if (argc>4) sscanf(argv[4], "%d", &LEVEL_HEIGHTTEXT);
	if (argc>5) sscanf(argv[5], "%d", &COLOR_HEIGHTTEXT);
	if (argc>6) sscanf(argv[6], "%lf", &TOLERANCE);
		
	if(mdlDialog_fileOpen(path, NULL, NULL, NULL, NULL, tcb->dgnfilenm, "请指定要处理的任一文件,同目录下所有文件都将处理")==TRUE)
	{
		strcpy(str,"你取消了这次操作");
		mdlOutput_prompt(str);
		goto end;
	}
								//选定要处理的文件
	strcpy(newpath, path);
	newpname=strrchr(newpath, '\\');
	strcpy(newpname,"\\new\\");
	newpname=strrchr(newpath, '\\')+1;
								//确定定目标文件目录
	pname=strrchr(path, '\\')+1;
	strcpy(pname, "*.*");
	mdlFile_findFiles (&fileInfoP, &fileCount, path, FF_NORMAL);
	while (fileCount)
	{
		fileCount--;
		strcpy(pname, fileInfoP[fileCount].name);	//源文件名 
		strcpy(newpname, fileInfoP[fileCount].name);	//目标文件名

		strcpy(fname, newpath);	
		tmp=strrchr(fname,'.');
		strcpy(tmp, ".log");				//日志文件名

		mdlSystem_newDesignFile(path);
		process(newpath, fname);
	}
	free (fileInfoP);
	mdlOutput_status("大功告成啦!");

end:	mdlSystem_unloadMdlProgram("annolink");
}

void GetFirstPoint(MSElementDescr *emd, Dpoint3d *dp)
{
	switch (emd->el.ehdr.type)
	{
		case 2:
			mdlCell_extract(dp, NULL, NULL, NULL, NULL, &emd->el);
			break;
		case 17:
			mdlText_extract(NULL, dp, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, &emd->el);
			break;
		default:
			if (mdlElmdscr_extractEndPoints(dp, NULL, NULL, NULL, emd, 0)!=SUCCESS)
			{
				dp->x=0, dp->y=0, dp->z=0;
			}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -