天天看點

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

繼續閱讀