一、本節課程
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