|
一、本节课程
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。 |
|