找回密码
 立即注册

QQ登录

只需一步,快速开始

扫一扫,访问微社区

查看: 814|回复: 5

[每日一码] ObjectARX 5个常用代码

[复制链接]

已领礼包: 13个

财富等级: 恭喜发财

发表于 2016-10-31 14:05:00 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能,让你轻松玩转社区。

您需要 登录 才可以下载或查看,没有账号?立即注册

×
本帖最后由 LoveArx 于 2016-10-26 14:55 编辑

//加载一个实体到数据库,返回实体ID
static AcDbObjectId LoadEntity(AcDbEntity* entity)  
{  
        AcDbBlockTable* pBlockTable;  
        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlockTable,AcDb::kForRead);  
        AcDbBlockTableRecord* pBlockTableRecord;  
        pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite);  

        AcDbObjectId Id;  
        pBlockTableRecord->appendAcDbEntity(Id,entity);  
        pBlockTable->close();  
        pBlockTableRecord->close();  

        entity->close();  
        return Id;  
}


static int SelColor()  
{  
        ////先获得当前层的ID  
        AcDbObjectId layerId = acdbHostApplicationServices()->workingDatabase()->clayer();  
        ////然后获得当前层指针  
        AcDbLayerTableRecordPointer ptLayer(layerId,AcDb::OpenMode::kForRead);  
        ////获得当前层的颜色  
        AcCmColor oldColor = ptLayer->color();  
        int nCurColor = oldColor.colorIndex();//当前层的颜色  
        int nNewColor = oldColor.colorIndex();//用户选择的颜色  


        if (acedSetColorDialog(nNewColor,Adesk::kFalse,nCurColor))  
        {  


                return nNewColor;  
        }  
        else  
        {  


                return nCurColor;  
        }  
} 


//第一题:定义一个全局命令,功能:使用全局函数创建一个简单实体-直线,顶点由用户输入;
static void TESTlineCmd()  
{  
        ads_point inputStart;  
        ads_point inputEnd;  

        AcGePoint3d ptStart;  
        AcGePoint3d ptEnd;  

        ////用户输入要画的坐标  
        if (acedGetPoint(NULL,_T("\nstart point"),inputStart) != RTNORM)  
        {  

                return;  
        }  
        ptStart[X] = inputStart[X];  
        ptStart[Y] = inputStart[Y];  
        ptStart[Z] = inputStart[Z];  

        if (acedGetPoint(NULL,_T("\nend point"),inputEnd) != RTNORM)  
        {  
                return;  
        }  
        ptEnd[X] = inputEnd[X];  
        ptEnd[Y] = inputEnd[Y];  
        ptEnd[Z] = inputEnd[Z];  


        AcDbLine* pLine = new AcDbLine(ptStart,ptEnd);  
        int colorIndex = SelColor();  
        AcCmColor color;  
        color.setColorIndex(colorIndex);  
        pLine->setColor(color);  
        LoadEntity(pLine);  
} 


/第二题:定义一个LISP函数,功能:使用全局函数创建一个简单实体-圆,返回圆的实体数据链表,圆心和半径由用户输入;
static int ads_circle()  
{  
        ads_point pt;  
        if(acedGetPoint(NULL,_T("\n选择圆心"),pt) != RTNORM)  
        {  
                return 0;  
        }  
        ads_real realNum;  
        if(acedGetReal(_T("\n输入半径"),&realNum)!= RTNORM)  
        {  
                return 0;  
        }  
        ////垂直平面法向量  
        AcGeVector3d vec(0,0,1);  
        ////圆心  
        AcGePoint3d ptCenter(pt[X],pt[Y],pt[Z]);  
        AcDbCircle* pCircle = new AcDbCircle(ptCenter,vec,realNum);  

        LoadEntity(pCircle);  

        ////打印出类型为字符串的接收参数  
        resbuf* pInput = acedGetArgs();  
        CString str;  
        while (pInput != NULL)  
        {  
                if (pInput->resval.rstring != NULL)  
                {  
                        acutPrintf(pInput->resval.rstring);  
                        acutPrintf(_T("\n"));  
                }  
                pInput = pInput->rbnext;  
        }  
        ////构造圆形实体  
        struct resbuf* rb ;  
        rb = acutBuildList(  
                RTDXF0,_T("CIRCLE"),  
                62,1,//1 == RED  
                10,ptCenter,  
                40,realNum,//radius  
                0);  
        acedRetList(rb);  
        return RTNORM;  
}


//第三题;输入三点,以中间点为顶点,把旁边两条线做圆角,半径用户输入

static void TESTcomplexentcmd()  
{  
        ads_point pt1;  
        ads_point pt2;  
        ads_point pt3;  
        ads_real r;  

        if (acedGetPoint(NULL,_T("\n输入第一点"),pt1) != RTNORM)  
        {  
                return;  
        }  

        if (acedGetPoint(NULL,_T("\n输入第二点"),pt2) != RTNORM)  
        {  
                return;  
        }  

        if (acedGetPoint(NULL,_T("\n输入第三点"),pt3) != RTNORM)  
        {  
                return;  
        }  

        if (acedGetReal(_T("\n输入内切圆半径"),&r) != RTNORM)  
        {  
                return;  
        }  
        ////坐标维度转化  
        AcGePoint3d pt3d1 = asPnt3d(pt1);  
        AcGePoint3d pt3d2 = asPnt3d(pt2);  
        AcGePoint3d pt3d3 = asPnt3d(pt3);  

        ////构造两条直线计算顶点到切点的距离  
        AcDbLine line1(pt3d2,pt3d1);  
        AcDbLine line2(pt3d2,pt3d3);  

        ////得到以PT2为顶点的两个向量  
        AcGeVector3d v1(pt1[X]-pt2[X],pt1[Y]-pt2[Y],pt1[Z] - pt2[Z]);  
        AcGeVector3d v2(pt3[X]-pt2[X],pt3[Y] - pt2[Y],pt3[Z] - pt2[Z]);  
        AcGeVector3d v3(0,0,1);  

        double PI = 3.1415926536;  
        ////计算两个向量的夹角  

        double angle = v1.angleTo(v2,v3);  
        double angle1 = angle > PI ? 2 * PI - angle : angle;  

        ////计算切点到顶点距离  
        double dist = r / tan(angle1 / 2);  

        ////切点1  
        AcGePoint3d ptQ1;  
        ////切点2  
        AcGePoint3d ptQ2;  

        ////找到切点  
        line1.getPointAtDist(dist,ptQ1);  
        line2.getPointAtDist(dist,ptQ2);  

        ////求出bulge值(是圆心角1/4的正切值 - - ,之前当成正切值的四分之一了 - -!!!)  
        double bulge;  
        bulge = tan((PI - angle1) / 4);  
        if(angle > 0 && angle <= PI)  
        {  
                bulge = - bulge;  
        }  

        AcDbPolyline* pl = new AcDbPolyline();  
        AcGePoint2d pt2d1(pt3d1[X],pt3d1[Y]);  
        AcGePoint2d pt2dq1(ptQ1[X],ptQ1[Y]);  
        AcGePoint2d pt2dq2(ptQ2[X],ptQ2[Y]);  
        AcGePoint2d pt2d3(pt3d3[X],pt3d3[Y]);  

        pl->addVertexAt(0,pt2d1,0);  
        pl->addVertexAt(1,pt2dq1,bulge);  
        pl->addVertexAt(2,pt2dq2,0);  
        pl->addVertexAt(3,pt2d3,0);  

        LoadEntity(pl);  

        CString out;  
        out.Format(_T("\nangle:%.2f,bulge:%.2f,\ndist:%.2f\n,pt[z]:%.2f,%.2f,%.2f"),angle,bulge,dist,pt1[Z],pt2[Z],pt3[Z]);  
        acutPrintf(out);  
}  


//第四题:定义一个全局命令,功能:使用类库创建一个块表记录,并插入块;
[it618postdisplay>0]
static void TESTaddblkcmd()  
{  
        ////根据用户的输入设置块表记录的名称  
        CString blkName;  
        if (acedGetString(Adesk::kFalse,_T("\n输入块名称"),blkName.GetBuffer(20)) != RTNORM)  
        {  
                return;  
        }  


        ////用完getBuffer要及时release  
        blkName.ReleaseBuffer();  

        AcDbBlockTable* pBlkTbl;  
        acdbHostApplicationServices()->workingDatabase()->getBlockTable(pBlkTbl,AcDb::kForWrite);  

        AcDbObjectId rcdId ;  

        ////如果没有,添加新的  
        if (!pBlkTbl->has(blkName))  
        {  
                ////创建新块  
                AcDbBlockTableRecord* pBlkTblRcd;  
                pBlkTblRcd = new AcDbBlockTableRecord();  
                pBlkTblRcd->setName(blkName);  

                ////将块表记录添加到块表中,设置ID  
                pBlkTbl->add(rcdId,pBlkTblRcd);  

                ////向块表记录中添加实体  
                AcGePoint3d ptStart(-10,0,0),ptEnd(10,0,0);  
                AcDbLine* pLine1 = new AcDbLine(ptStart,ptEnd);  
                ptStart.set(0,-10,0);  
                ptEnd.set(0,10,0);  
                AcDbLine *pLine2 = new AcDbLine(ptStart,ptEnd);  

                AcGeVector3d vecNormal(0,0,1);  
                AcDbCircle *pCircle = new AcDbCircle(AcGePoint3d::kOrigin,vecNormal,6);  
                AcDbObjectId entId;  
                pBlkTblRcd->appendAcDbEntity(entId,pLine1);  
                pBlkTblRcd->appendAcDbEntity(entId,pLine2);  
                pBlkTblRcd->appendAcDbEntity(entId,pCircle);  
                ////关闭实体块表记录  

                pLine1->close();  
                pLine2->close();  
                pCircle->close();  
                pBlkTblRcd->close();  

        }////如果已经有了,那就根据名字读出RECORDID,插入块参照时会用到  
        else  
        {  
                pBlkTbl->getAt(blkName,rcdId,false);////以读的方式获取  
        }  

        ////在和用户交互之前,需要关闭块表,否则容易出错  
        pBlkTbl->close();  
        ////插入块  

        ////获得用户输入的块参照的插入点  
        ads_point pt;  
        if(acedGetPoint(NULL,_T("\n输入块参照的插入点"),pt) != RTNORM)  
        {  
                pBlkTbl->close();  
                return;  
        }  
        AcGePoint3d ptInsert = asPnt3d(pt);  

        ////创建块参照  
        AcDbBlockReference* pBlkRef = new AcDbBlockReference(ptInsert,rcdId);  

        ////将块参照添加到模型空间  

        AcDbBlockTableRecord* pBlkTblRcd2;  
        pBlkTbl->getAt(ACDB_MODEL_SPACE,pBlkTblRcd2,AcDb::kForWrite);  
        pBlkTblRcd2->appendAcDbEntity(pBlkRef);  

        ////关闭数据库对象  
        pBlkRef->close();  
        pBlkTblRcd2->close();  
        pBlkTbl->close();  
}  

[/it618postdisplay]

//第五题:定义一个命令,功能:让用户选择界面上的直线实体,然后修改所有选中实体的颜色;
static void TESTchangecolorcmd()  
{  
        ads_name ssname;  
        resbuf strFilter;  
        ////只能选择直线对象,构造选择集过滤器,只能选直线  
        strFilter.resval.rstring = _T("LINE");  
        strFilter.rbnext = NULL;  
        strFilter.restype = 0;  

        ////选择多个实体,传递NULL,让用户自己来选  
        if(acedSSGet(NULL,NULL,NULL,&strFilter,ssname) != RTNORM)  
        {  
                return;  
        }  

        long len;  
        acedSSLength(ssname,&len);  
        CString ss;  
        ss.Format(_T("已选中%d个实体"),len);  
        acutPrintf(ss);  

        ads_name entname;  

        AcDbObjectId id;  
        AcDbEntity* ent = NULL;  
        CString strName;  

        ////弹出颜色选择对话框,选中一个颜色,默认是当前层的颜色  
        int nNewColor = SelColor();  

        for (int i=0;i<len;i++)  
        {  
                if (acedSSName(ssname, i, entname) == RTNORM)  
                {  

                        ////根据名称得到ID  
                        acdbGetObjectId(id,entname);  

                        ////以写模式,根据ID索引到对象,并打开ENTITY  
                        acdbOpenObject(ent,id,AcDb::OpenMode::kForWrite);  
                        strName.Format(_T("%d"),ent->colorIndex());  
                        acutPrintf(_T("\n"));  
                        acutPrintf(strName);  

                        ent->setColorIndex(nNewColor);  
                        ent->close();  
                }  
        }  
        acedSSFree(ssname);  
}  



//-----------------------------------------------------------------------------  
IMPLEMENT_ARX_ENTRYPOINT(CArxProject2App)  


        ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject2App, TEST, lineCmd, lineCmd, ACRX_CMD_MODAL, NULL)  


        //ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject2App, TEST, circlecmd, circlecmd, ACRX_CMD_MODAL, NULL)  


        ACED_ADSSYMBOL_ENTRY_AUTO(CArxProject2App, circle, false)  


        ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject2App, TEST, changecolorcmd, changecolorcmd, ACRX_CMD_MODAL, NULL)  


        ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject2App, TEST, addblkcmd, addblkcmd, ACRX_CMD_MODAL, NULL)  


        ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject2App, TEST, complexentcmd, complexentcmd, ACRX_CMD_MODAL, NULL)  


论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!

已领礼包: 2963个

财富等级: 家财万贯

发表于 2016-11-1 08:56:37 | 显示全部楼层
谢谢分享,慢慢学习
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 2450个

财富等级: 金玉满堂

发表于 2016-11-4 15:41:19 | 显示全部楼层
学习!!!!!!!!!!!!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复

使用道具 举报

已领礼包: 1个

财富等级: 恭喜发财

发表于 2016-11-5 07:25:40 | 显示全部楼层
小手一抖 代码顺走 3Q3Q
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

已领礼包: 69个

财富等级: 招财进宝

发表于 2017-9-2 22:42:59 | 显示全部楼层
好代码,学习学习!!!
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

发表于 2017-9-6 08:58:07 | 显示全部楼层
感谢分享,学习中
论坛插件加载方法
发帖求助前要善用【论坛搜索】功能,那里可能会有你要找的答案;
如果你在论坛求助问题,并且已经从坛友或者管理的回复中解决了问题,请把帖子标题加上【已解决】;
如何回报帮助你解决问题的坛友,一个好办法就是给对方加【D豆】,加分不会扣除自己的积分,做一个热心并受欢迎的人!
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

QQ|申请友链|Archiver|手机版|小黑屋|辽公网安备|晓东CAD家园 ( 辽ICP备15016793号 )

GMT+8, 2024-9-24 20:30 , Processed in 0.200199 second(s), 38 queries , Gzip On.

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

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