OBJECT ARX 源码
/加载一个实体到数据库,返回实体IDstatic 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 = inputStart;
ptStart = inputStart;
ptStart = inputStart;
if (acedGetPoint(NULL,采用T("\nend point"),inputEnd) != RTNORM)
{
return;
}
ptEnd = inputEnd;
ptEnd = inputEnd;
ptEnd = inputEnd;
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,pt,pt);
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-pt2,pt1-pt2,pt1 - pt2);
AcGeVector3d v2(pt3-pt2,pt3 - pt2,pt3 - pt2);
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,pt3d1);
AcGePoint2d pt2dq1(ptQ1,ptQ1);
AcGePoint2d pt2dq2(ptQ2,ptQ2);
AcGePoint2d pt2d3(pt3d3,pt3d3);
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:%.2f,%.2f,%.2f"),angle,bulge,dist,pt1,pt2,pt3);
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;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)
页:
[1]