admin 发表于 2024-2-28 09:00:34

OBJECT ARX 源码

/加载一个实体到数据库,返回实体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 = 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]
查看完整版本: OBJECT ARX 源码