C++ ARX二次开发视图、视口、UCS

视频课程由yunyou.ke.qq.com提供

一、本节课程
C++ ARX二次开发视图、视口、UCS

二、本节要讲解的知识点

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

2C++ARX开发中视口的相关概念及设置

3UCS相关概念、获取和修改

三、具体内容

1、开发视图的思路:

AcDbViewTableRecord 来表示AUTOCAD中的视图。

 

如何调整视图:先获取当前视图,设置一些特性,然后acedSetCurrentView函数来更新视图。

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

VIEWMODEVIEWCTRLENSLENGTHTARGETVIEWDIRVIEWSIZESCREENSIZE

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;

 

AcGePoint3dpt1Wcs=CConvertUtil::UcsToWcsPoint(asPnt3d(pt1));

AcGePoint3dpt2Wcs=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类里面定义了一个函数SetSetCenter

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

4、应用视图相关知识实现了ZoomExtentZoomEntityZoomWindow

你可能感兴趣的:(ObjectARX,CAD二次开发,ARX,C++,视图,视口)