天天看点

C++ ARX二次开发视图

一、本节课程

C++ ARX二次开发视图

二、本节要讲解的知识点

C++ ARX开发中视图的获取、设置等知识

三、具体内容

1、AcDbViewTableRecord 来表示AUTOCAD中的视图。如何调整视图:先获取当前视图,设置一些特性,然后acedSetCurrentView函数来更新视图。

2、与视图相关的系统变量,来获取当前视图的一些参数。

VIEWMODE、VIEWCTR、LENSLENGTH、TARGET、VIEWDIR、VIEWSIZE、SCREENSIZE

void CViewUtil::GetCurrentView(AcDbViewTableRecord &view)
    {
    	struct resbuf rb;
    	struct resbuf wcs,ucs,dcs;
    	wcs.restype=RTSHORT;
    	wcs.resval.rint=0;
    	ucs.restype=RTSHORT;
    	ucs.resval.rint=1;
    	dcs.restype=RTSHORT;
    	dcs.resval.rint=2;
    //获得当前视口的查看模式
    acedGetVar(TEXT("VIEWMODE"),&rb);
    view.setPerspectiveEnabled((rb.resval.rint&1)!=0);
    view.setFrontClipEnabled((rb.resval.rint&2)!=0);
    view.setBackClipEnabled((rb.resval.rint&4)!=0);
    view.setFrontClipAtEye((rb.resval.rint&16)==0);

//当前视口中视图的中心点(UCS坐标)
acedGetVar(TEXT("VIEWCTR"),&rb);
acedTrans(rb.resval.rpoint,&ucs,&dcs,0,rb.resval.rpoint);
view.setCenterPoint(AcGePoint2d(rb.resval.rpoint[X],rb.resval.rpoint[Y]));

//当前视口透视图中的镜头焦距长度(单位为毫米)
acedGetVar(TEXT("LENSLENGTH"),&rb);
view.setLensLength(rb.resval.rreal);

//当前视口中目标点的位置(UCS坐标表示)
acedGetVar(TEXT("TARGET"),&rb);
acedTrans(rb.resval.rpoint,&ucs,&wcs,0,rb.resval.rpoint);
view.setTarget(AcGePoint3d(rb.resval.rpoint[X],rb.resval.rpoint[Y],rb.resval.rpoint[Z]));

//当前视口的观察方向(UCS)
acedGetVar(TEXT("VIEWDIR"),&rb);
acedTrans(rb.resval.rpoint,&ucs,&wcs,1,rb.resval.rpoint);
view.setViewDirection(AcGeVector3d(rb.resval.rpoint[X],rb.resval.rpoint[Y],rb.resval.rpoint[Z]));

//当前视口的视图高度(图形单位)
acedGetVar(TEXT("VIEWSIZE"),&rb);
view.setHeight(rb.resval.rreal);
double height=rb.resval.rreal;

//以像素为单位的当前视口的大小(X和Y值)
acedGetVar(TEXT("SCREENSIZE"),&rb);
view.setWidth(rb.resval.rpoint[X]/rb.resval.rpoint[Y]*height);

//当前视口的视图扭转角
acedGetVar(TEXT("VIEWTWIST"),&rb);
view.setViewTwist(rb.resval.rreal);
//将模型选项卡或最后一个布局选项卡置为当前
acedGetVar(TEXT("TILEMODE"),&rb);
int tileMode=rb.resval.rint;

//设置当前视口的标识码
acedGetVar(TEXT("CVPORT"),&rb);
int cvport=rb.resval.rint;
//是否是模型空间的视图
bool paperspace=((tileMode==0) && (cvport==1)) ?true:false;
view.setIsPaperspaceView(paperspace);
if (!paperspace)
{
	acedGetVar(TEXT("FRONTZ"),&rb);
	view.setFrontClipDistance(rb.resval.rreal);

	acedGetVar(TEXT("BACKZ"),&rb);
	view.setBackClipDistance(rb.resval.rreal);
}
else
{
	view.setFrontClipDistance(0.0);
	view.setBackClipDistance(0.0);
}
           

}

3、使用acedSetCurrentView(&view,NULL);来更新我们的视图。

4、比较有用的工具函数:

AcDbObjectIdArray CDwgDatabaseUtil::GetAllEntityIds(const TCHAR* layerName)
{
	AcDbObjectIdArray entIds;
	bool bFilterLayer=false;
	AcDbObjectId layerId;
	if (layerName!=NULL)
	{
		AcDbLayerTable *pLayerTbl=NULL;
		acdbHostApplicationServices()->workingDatabase()->getSymbolTable(pLayerTbl,AcDb::kForRead);
		if (!pLayerTbl->has(layerName))
		{
			pLayerTbl->close();
			return entIds;
		}
		pLayerTbl->getAt(layerName,layerId);
		pLayerTbl->close();
		bFilterLayer=true;
	}
	AcDbBlockTable *pBlkTbl=NULL;
	acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl,AcDb::kForRead);

  AcDbBlockTableRecord *pBlkTblRcd=NULL;
  pBlkTbl->getAt(ACDB_MODEL_SPACE,pBlkTblRcd,AcDb::kForRead);
  pBlkTbl->close();

  AcDbBlockTableRecordIterator *it=NULL;
  pBlkTblRcd->newIterator(it);
  for (it->start();!it->done();it->step())
  {
    	AcDbEntity *pEnt=NULL;
    	Acad::ErrorStatus es=it->getEntity(pEnt,AcDb::kForRead);
	   if (es==Acad::eOk)
	  {
	    	if (bFilterLayer)
	    	{
			   if (pEnt->layerId()==layerId)
			{
				  entIds.append(pEnt->objectId());
			}
		}
		else
		{
			entIds.append(pEnt->objectId());
		}
		pEnt->close();
	}
	else
	{
		acutPrintf(TEXT("CDwgDatabaseUtil::GetAllEntityIds打开实体失败的错误代码是%d"),(int)es);
	}
}
delete it;
pBlkTblRcd->close();
return entIds;
           

}

5、使用视图:

static void YunyouMyGroupZoomWindow () {
	ads_point pt1,pt2;
	if (acedGetPoint(NULL,TEXT("\n输入第一个角点:"),pt1) !=RTNORM )return;
	if (acedGetCorner(pt1,TEXT("\n输入第二个角点:"),pt2) !=RTNORM )return;
	AcGePoint3d	pt1Wcs=CConvertUtil::UcsToWcsPoint(asPnt3d(pt1));
	AcGePoint3d	pt2Wcs=CConvertUtil::UcsToWcsPoint(asPnt3d(pt2));
	CViewUtil::Set(pt1Wcs,pt2Wcs,1.0);
}

static void YunyouMyGroupZoomExtents () {
	CViewUtil::ZoomExtent();
}

static void YunyouMyGroupZoomEntity () {

	AcDbObjectIdArray allEntIds=CDwgDatabaseUtil::GetAllEntityIds();
    bool bFound=false;
	AcDbExtents ext;
	for (int i=0;i<allEntIds.length();i++)
	{
		AcDbCircle *pCircle=NULL;
		if (acdbOpenObject(pCircle,allEntIds[i],AcDb::kForRead)==Acad::eOk)
		{
			pCircle->getGeomExtents(ext);
			bFound=true;
			pCircle->close();
		}

		if (bFound)
		{
			CViewUtil::Set(ext.minPoint(),ext.maxPoint(),5.0);
		}
	}
}
           

四、总结

1、怎么样获取当前视图:CViewUtil类里面定义了一个函数GetCurrentView。

2 、怎样设置视图:CViewUtil类里面定义了一个函数Set、SetCenter。

3、循环迭代模型空间里面的实体,取出实体的ID,放置到ID数组。

4、应用视图相关知识实现了ZoomExtent、ZoomEntity、ZoomWindow。

5、在线视频课程提供者: yunyou.ke.qq.com

继续阅读