天气与日历 切换到窄版

 找回密码
 立即注册
中国膜结构网
十大进口膜材评选 十大国产膜材评选 十大膜结构设计评选 十大膜结构公司评选
查看: 45|回复: 0

ARX二次开发视图

[复制链接]

该用户从未签到

主题

0

回帖

2912

积分

管理员

积分
2912
发表于 2024-6-22 09:46:18 | 显示全部楼层 |阅读模式
一、本节课程
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。

 

 

 

 

ARX二次开发视图
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|Archiver|中国膜结构网|中国膜结构协会|进口膜材|国产膜材|ETFE|PVDF|PTFE|设计|施工|安装|车棚|看台|污水池|中国膜结构网_中国空间膜结构协会

GMT+8, 2024-11-1 13:22 , Processed in 0.138050 second(s), 26 queries .

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

快速回复 返回顶部 返回列表