1、C++ ARX开发中视图的获取、设置等知识
2、C++ARX开发中视口的相关概念及设置
3、UCS相关概念、获取和修改
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;
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类里面定义了一个函数Set、SetCenter。
3、循环迭代模型空间里面的实体,取出实体的ID,放置到ID数组。
4、应用视图相关知识实现了ZoomExtent、ZoomEntity、ZoomWindow。