OBJECT ARX 总结5道题

/加载一个实体到数据库,返回实体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;
}////函数在调用的时候需要加上括号 (func "param")

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

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);
 
 
}


 

//第四题:定义一个全局命令,功能:使用类库创建一个块表记录,并插入块;

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();
 
 
 
 
}


//第五题:定义一个命令,功能:让用户选择界面上的直线实体,然后修改所有选中实体的颜色;
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;icolorIndex());
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)

 

 

 

 

你可能感兴趣的:(ObjectArx)