您的当前位置:首页正文

(完整版)ObjectARX学习笔记

2020-09-14 来源:易榕旅网


一、 CAD 版本和 VC++的版本对应 ...................................................................................... 1 二、ObjectARX 实体创建 ............................................................................................................... 1 三、 创建直线实例 ................................................................................................................... 1 五、修改图形对象的属性 ............................................................................................................... 2

1、打开图形数据库的对象 ..................................................................................................... 2 2、修改直线颜色实例 ............................................................................................................. 3 六、用类组织函数 ........................................................................................................................... 4 七、提高 CreateLine 函数的可重用性 ........................................................................................... 8 八、升级 Visual Studio 试用版到正式版 ..................................................................................... 12 九、创建圆..................................................................................................................................... 13 十、创建圆弧(“三点法”,“起点、圆心、终点法”,“起点、圆心、圆弧角度法”) ..........................................................................................................................................................18

//添加计算常量的值的函数 ............................................................................................. 20 十一、创建多段线 ......................................................................................................................... 23 十二、创建正多边形 ..................................................................................................................... 25

创建时间:2013/11/27 9:06:00

一、CAD 版本和 VC++的版本对应AutoCAD

Visual Studio

2000——2002 VC6.0 2004——2006 VC7.0(VC.NET2002) 2007——2009 VC8.0(VC2005) 2010——1012 VC2008 2013——2014 VC2010 二、ObjectARX 实体创建

1、注册一条直线命令

2、在命令函数中添加创建直线对象函数(AcDbLine 类) AcGePoint3d ptStart(); AcGePoint3d ptEnd();

AcDbLine *pLine=new AcDbLine(ptStart,ptEnd); 3 在命令函数中添加获得指向块表的指针相关代码

AcDbBlockeTable *pBlockTable;

acdbHostApplicationServices()->WorkingDataBase()- >getBlockTable(pBlockTable,AcDb::kForRead);

4、在命令函数中添加获得指向特定块表记录的指针的相关代码AcDbBlockTableRecord *pBlockTableRecord;

pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); 5、在命令函数中添加向块表记录中附加实体代码 AcDbObjectId lineId;

pBlockTabelRecord->appendAcDbEntity(lineId,pLine); 6、在命令函数中添加关闭图形数据库各种对象的代码

pBlockTable->close();pBlockTableRecord->close();pLine->close(); 三、创建直线实例

创建时间:2013/11/27 9:06:00

Comme nt [M1]: 一个在结构 Acad 中 定义的枚举 ErrorStatus 表示函数的 执行结 果

四、

五、修改图形对象的属性 1、打开图形数据库的对象 Acad::ErrorStatus acdbOpenAcDbEntity(AcDbEntity id,AcDb::Openmode mode, bool openErasedEntity=false); 第一个参数返回值指向图形数据库实体的指针;第二个参数输入了要获得的实体的 ID 号,第三个参数指定了打开该实体的方式(读或写);第四个参数指定是否允许访问一个已经被删除的实体。 *&pEnt,AcDbObjectId 创建时间:2013/11/27 9:06:00

2、修改直线颜色实例 static AcDbObjectId CreatLine() { //在内存上创建一个新的AcDbLine对象AcGePoint3d ptStart(0,0,0); AcGePoint3d ptEnd(100,100,0); AcDbLine *pLine=new AcDbLine(ptStart,ptEnd); //获得指向块表的指针AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead); //获得指向特定块表记录的指针AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); //将对象添加到块表记录中AcDbObjectId lineId; pBlockTableRecord->appendAcDbEntity(lineId,pLine); //关闭图形数据库的各种对象pBlockTable->close(); pBlockTableRecord->close(); pLine->close(); //为在命令函数中引用该函数,需要返回lineId return lineId; }

static Acad::ErrorStatus ChangeColor(AcDbObjectId entId,Adesk::UInt16 colorIndex){ AcDbEntity *pEntity; //打开图形数据库中的对象acdbOpenObject(pEntity,entId,AcDb::kForWrite); //修改实体颜色 pEntity->setColorIndex(colorIndex); //关闭实体对象pEntity->close(); //被命令函数引用时需返回值 return Acad::eOk;

} // - mshlModifyEnt.ChangeColor command (do not rename) static void mshlModifyEntChangeColor(void) { // Add your code for command mshlModifyEnt.ChangeColor here //创建直线AcDbObjectId lineId; 创建时间:2013/11/27 9:06:00 Comment [M2]: CreateLine 函数要被命令函数调用,故要放在命令函数之前,并要注明函数类型 AcDbObjectId 以及成员类型 ststic.下面 Modify 函数同。

lineId=CreatLine(); //修改直线颜色ChangeColor(lineId,1); } Comment [M3]: 这些函数都是放在 acrxEntryPoint.cpp 文件中 Comment [M4]: 包含 六、用类组织函数 1、新建 ObjectARX 项目 CreatEnt 2、新建两个 C++类 CreatEnt 和 ModifyEnt #include \"StdAfx.h\" 下头文件同

用这个类保存创建实体的函数头文件 #pragma once #include \"StdAfx.h\" class CCreatEnt { public: CCreatEnt(void); ~CCreatEnt(void); static AcDbObjectId CreatLine(); }; 源文件 #include \"StdAfx.h\" #include \"CreatEnt.h\" CCreatEnt::CCreatEnt(void) { } 创建时间:2013/11/27 9:06:00

CCreatEnt::~CCreatEnt(void) { }

AcDbObjectId CCreatEnt::CreatLine() {

//在内存上创建一个新的AcDbLine对象AcGePoint3d ptStart(0,0,0); AcGePoint3d ptEnd(100,100,0);

AcDbLine *pLine=new AcDbLine(ptStart,ptEnd); //获得指向块表的指针

AcDbBlockTable *pBlockTable;

acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead);

//获得指向特定块表记录的指针

AcDbBlockTableRecord *pBlockTableRecord;

pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); //将对象添加到块表记录中AcDbObjectId lineId;

pBlockTableRecord->appendAcDbEntity(lineId,pLine); //关闭图形数据库的各种对象pBlockTable->close(); pBlockTableRecord->close(); pLine->close(); return lineId; } 头文件 #pragma once #include \"StdAfx.h\"

class CModifyEnt { public:

CModifyEnt(void); ~CModifyEnt(void);

static Acad::ErrorStatus ChangeColor(AcDbObjectId entId,Adesk::UInt16 colorIndex); }; 源文件

#include \"StdAfx.h\" #include \"ModifyEnt.h\" CModifyEnt::CModifyEnt(void) { }

创建时间:2013/11/27 9:06:00

CModifyEnt::~CModifyEnt(void) { }

Acad::ErrorStatus CModifyEnt::ChangeColor(AcDbObjectId entId, Adesk::UInt16 colorIndex) {

AcDbEntity *pEntity; //打开图形数据库中的对象

acdbOpenObject(pEntity,entId,AcDb::kForWrite); //修改实体颜色

pEntity->setColorIndex(colorIndex); //关闭实体对象pEntity->close(); return Acad::eOk; }

AcrxEntryPoint.cpp

// (C) Copyright 2002-2007 by Autodesk, Inc. //

// Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. //

// AUTODESK PROVIDES THIS PROGRAM \"AS IS\" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. //

// Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. //

//----------------------------------------------------------------------------- // ----- acrxEntryPoint.cpp

//----------------------------------------------------------------------------- #include \"StdAfx.h\" #include \"resource.h\"

创建时间:2013/11/27 9:06:00

#include \"CreatEnt.h\" #include \"ModifyEnt.h\" //----------------------------------------------------------------------------- Comment [M5]: 在 acrxEntryPoint.cpp 中包含 CreateEnt.h 和 ModifyEnt.h 否则会提示该两个自定义类“不是类或#define szRDS _RXST(\"mshl\")

//----------------------------------------------------------------------------- // ----- ObjectARX EntryPoint class CCreatEntsApp : public AcRxArxApp {

public: CCreatEntsApp () : AcRxArxApp () {}

virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) { // TODO: Load dependencies here

// You *must* call On_kInitAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;

// TODO: Add your initialization code here return (retCode) ; } virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) { // TODO: Add your code here

// You *must* call On_kUnloadAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

// TODO: Unload dependencies here return (retCode) ; } virtual void RegisterServerComponents () { }

// - mshlCreatEnts.ChangeColor command (do not rename) static void mshlCreatEntsChangeColor(void) { // Add your code for command mshlCreatEnts.ChangeColor here //创建直线AcDbObjectId lineId; lineId=CCreatEnt::CreatLine(); 创建时间:2013/11/27 9:06:00 命名空间名称”并生成失败

//修改直线颜色CModifyEnt::ChangeColor(lineId,1); } } ; Comment [M6]:

//----------------------------------------------------------------------------- IMPLEMENT_ARX_ENTRYPOINT(CCreatEntsApp) ACED_ARXCOMMAND_ENTRY_AUTO(CCreatEntsApp, mshlCreatEnts, ChangeColor, ChangeColor, ACRX_CMD_TRANSPARENT, NULL) 七、提高 CreateLine 函数的可重用性 添加类 CCreateEnt 于是,CCreateEnt 类现在包含了两个静态成员函数: 头文件 #pragma once // 要 包 含 StdAfx #include \"StdAfx.h\" class CCreateLine { public: CCreateLine(void); ~CCreateLine(void); static AcDbObjectId CreateL(AcGePoint3d ptStart,AcGePoint3d ptEnd); static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt); }; 源文件 #include \"StdAfx.h\" #include \"CreateLine.h\" CCreateLine::CCreateLine(void) { }

CCreateLine::~CCreateLine(void) { }

AcDbObjectId CCreateLine::CreateL(AcGePoint3d ptStart, AcGePoint3d ptEnd) { 创建时间:2013/11/27 9:06:00

AcDbLine *pLine=new AcDbLine(ptStart,ptEnd); //

AcDbObjectId lineId;

lineId= CCreateLine::PostToModelSpace(pLine); return lineId; }

AcDbObjectId CCreateLine::PostToModelSpace(AcDbEntity *pEnt) {

AcDbBlockTable *pBlockTable;

acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord;

pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); AcDbObjectId entId;

pBlockTableRecord->appendAcDbEntity(entId,pEnt); pBlockTable->close(); pBlockTableRecord->close(); pEnt->close(); return entId; }

acrxEntryPoint.cpp

// (C) Copyright 2002-2007 by Autodesk, Inc. //

// Permission to use, copy, modify, and distribute this software in // object code form for any purpose and without fee is hereby granted, // provided that the above copyright notice appears in all copies and // that both that copyright notice and the limited warranty and // restricted rights notice below appear in all supporting // documentation. //

// AUTODESK PROVIDES THIS PROGRAM \"AS IS\" AND WITH ALL FAULTS. // AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC. // DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE // UNINTERRUPTED OR ERROR FREE. //

// Use, duplication, or disclosure by the U.S. Government is subject to // restrictions set forth in FAR 52.227-19 (Commercial Computer // Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii) // (Rights in Technical Data and Computer Software), as applicable. //

//-----------------------------------------------------------------------------

创建时间:2013/11/27 9:06:00

// ----- acrxEntryPoint.cpp //----------------------------------------------------------------------------- #include \"StdAfx.h\" #include \"resource.h\" Comment [M7]:

//一定要在EntryPoint中有包含自定义类的头文件 #include \"CreateLine.h\"

//----------------------------------------------------------------------------- #define szRDS _RXST(\"mshl\")

//----------------------------------------------------------------------------- // ----- ObjectARX EntryPoint class CArxProject1App : public AcRxArxApp {

public: CArxProject1App () : AcRxArxApp () {}

virtual AcRx::AppRetCode On_kInitAppMsg (void *pkt) { // TODO: Load dependencies here

// You *must* call On_kInitAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kInitAppMsg (pkt) ;

// TODO: Add your initialization code here return (retCode) ; } virtual AcRx::AppRetCode On_kUnloadAppMsg (void *pkt) { // TODO: Add your code here

// You *must* call On_kUnloadAppMsg here AcRx::AppRetCode retCode =AcRxArxApp::On_kUnloadAppMsg (pkt) ;

// TODO: Unload dependencies here return (retCode) ; } virtual void RegisterServerComponents () { } 创建时间:2013/11/27 9:06:00

// - mshlfengzhuanglei.AddLine command (do not rename) static void mshlfengzhuangleiAddLine(void) {

// Add your code for command mshlfengzhuanglei.AddLine here AcGePoint3d ptStart(0,0,0); AcGePoint3d ptEnd(100,100,0); AcDbObjectId lineId;

lineId=CCreateLine::CreateL(ptStart,ptEnd); } } ;

//----------------------------------------------------------------------------- IMPLEMENT_ARX_ENTRYPOINT(CArxProject1App)

ACED_ARXCOMMAND_ENTRY_AUTO(CArxProject1App, mshlfengzhuanglei, AddLine, AddLine, ACRX_CMD_MODAL, NULL)

2013/11/27

创建时间:2013/11/27 9:06:00

八、升级 Visual Studio 试用版到正式版

VS2008 注册方法:

非常简单,在开始>设置>控制面版>添加或删除程序>卸载 vs.net2008(名字不太记得了)>出现卸载界面>点击 Next>输入上面 CD-key ->出现成功画面即可完美将试用版升级成为正式版。

VS2008 正式版序列号 CDKEY:PYHYP-WXB3B-B2CCM-V9DX9-VDY8T

在 Windows 7 下,VS2008 试用版无法正常升级到正式版。原因是维护页面的注册码输入 框和升级按钮被隐藏。通过本补丁,可让注册码输入框和升级按钮恢复正常显示。然后输入激活码 PYHYP-WXB3B-B2CCM-V9DX9-VDY8T 点击升级 即可。 补丁下载地址 下载地址 2

九、创建圆 分别用“圆心,半径、”“直径的两个端点”、“三点法”创建圆 AcDbCircle 类用来表示圆,该类有两个构造函数,其形式为: AcDbCircle(); AcDbCircle(const AcGepoint3d& cntr,const AcGeVector3d& nrm,double radius); 两个构造函数名称相同,接受不同的参数,这是 C++中函数的重载。重载是 C++提供的一个很有用的特征,相同功能的函数采用相同的名称。 第二个构造函数接受更过的参数,因此首先对该函数进行封装,其他几个函数均以封 装后的函数为基础 程序框架: 本项目 CreateCircle 创建了两个自定义类:CCreateEnt 和 CCalculation。在 CCreateEnt 类中添加四个自定义函数: 1、 创建圆的函数 static AcDbObjectId CreateCircle(AcGePoint3d ptCenter,AcGeVector vec,double radius); 和 static AcDbObjectId PostToModelSpace(pEnt); 这两个函数与创建直线时相同 2、 创建在 XOY 平面上的圆的函数 Static AcDbObjectId CreateCircle(AcGepoint3d ptCenter,double radius); 该函数与 1 中的 CreateCircle 是函数重载,因为一般二维图形创建的圆都是在 XOY 平面上,故将 1 中的 vec 在此函数中设为(0,0,1),再返回 1 函数,以用圆心半径的方法创建圆。 3、两点法创建圆的函数 Static AcDbObjectId CreateCircle(AcGepoint2d pt1,AcGepoint2d pt2); 4、 三点法创建圆的函数 Static AcDbObjectId CreateCircle(AcGepoint2d pt1, AcGepoint2d pt2, AcGepoint2d pt3); 在 CCalculation 类中有一个自定义函数 Static AcGePoint2d MiddlePoint(AcGepoint2d pt1,AcGePoint2d pt2); 用来计算两点的中点 在 EntryPoint 函数中定义三个命令,分别用于三点法,两点法,圆心半径法创建圆。具体函数为: EntryPoint .cpp 函数 最后都要调用该被封装后的函数。 Comment [M8]: 不论以何种方法创建圆, // - mshlCreateCircle.AddCircle3 command (do not rename) //用三点法创建圆 static void mshlCreateCircleAddCircle3(void) { // Add your code for command mshlCreateCircle.AddCircle3 here AcGePoint2d pt1(300,200); AcGePoint2d pt2(400,400); AcGePoint2d pt3(800,600); AcDbObjectId circleId; circleId=CreateEnt::CreateCircle(pt1,pt2,pt3); } 创建时间:2013/11/27 9:06:00

// - mshlCreateCircle.1 command (do not rename) //用两点法创建圆

static void mshlCreateCircle1(void) {

// Add your code for command mshlCreateCircle.1 here AcGePoint2d pt1(100,400); AcGePoint2d pt2(400,400); AcDbObjectId circleId;

circleId=CreateEnt::CreateCircle(pt1,pt2); }

// - mshlCreateCircle.2 command (do not rename) //用圆心半径创建圆

static void mshlCreateCircle2(void) {

// Add your code for command mshlCreateCircle.2 here AcGePoint3d ptCenter(300,300,0); double radius=100;

CreateEnt::CreateCircle(ptCenter,radius); }

CreateEnt 类函数头文件 #pragma once #include \"StdAfx.h\" class CreateEnt { public:

CreateEnt(void); ~CreateEnt(void); //声明创建圆的函数

static AcDbObjectId CreateCircle(AcGePoint3d ptCenter,AcGeVector3d vec,double radius); static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt); //声明在XOY平面上创建圆的函数

static AcDbObjectId CreateCircle(AcGePoint3d ptCenter,double radius); //声明两点创建圆的函数

static AcDbObjectId CreateCircle(AcGePoint2d pt1,AcGePoint2d pt2); //声明三点创建圆的函数

static AcDbObjectId CreateCircle(AcGePoint2d pt1,AcGePoint2d pt2,AcGePoint2d pt3); };

源文件

#include \"StdAfx.h\" #include \"CreateEnt.h\" #include \"Calculation.h\"

创建时间:2013/11/27 9:06:00

CreateEnt::CreateEnt(void) { }

CreateEnt::~CreateEnt(void) { }

//封装AcDbCircle类的函数,即创建圆的函数

AcDbObjectId CreateEnt::CreateCircle(AcGePoint3d ptCenter, AcGeVector3d vec, double radius) {

AcDbCircle *pCircle=new AcDbCircle(ptCenter,vec,radius); AcDbObjectId circleId;

circleId=CreateEnt::PostToModelSpace(pCircle); return circleId; }

AcDbObjectId CreateEnt::PostToModelSpace(AcDbEntity *pEnt) {

AcDbBlockTable *pBlockTable;

acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord;

pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); AcDbObjectId entId;

pBlockTableRecord->appendAcDbEntity(entId,pEnt); pBlockTable->close(); pBlockTableRecord->close(); pEnt->close(); return entId; }

//添加新的函数CreateCircle(使用了函数重载的概念,函数名相同,但参数个数或者参数类型不同,为不同函数)

//用于创建位于XOY平面上的圆

AcDbObjectId CreateEnt::CreateCircle(AcGePoint3d ptCenter,double radius) {

AcGeVector3d vec(0,0,1);

return CreateEnt::CreateCircle(ptCenter,vec,radius); }

//添加两点创建圆的函数

AcDbObjectId CreateEnt::CreateCircle(AcGePoint2d pt1,AcGePoint2d pt2) {

//计算圆心和半径,调用MiddlePoint函数

AcGePoint2d pt=CCalculation::MiddlePoint(pt1,pt2); AcGePoint3d ptCenter(pt[X],pt[Y],0); double radius=pt1.distanceTo(pt2)/2;

创建时间:2013/11/27 9:06:00

//创建圆

return CreateEnt::CreateCircle(ptCenter,radius); }

//添加三点创建圆的函数

AcDbObjectId CreateEnt::CreateCircle(AcGePoint2d pt1, AcGePoint2d pt2, AcGePoint2d pt3) {

//使用几何类

AcGeCircArc2d geArc(pt1,pt2,pt3);

AcGePoint3d ptCenter(geArc.center().x,geArc.center().y,0); return CreateEnt::CreateCircle(ptCenter,geArc.radius()); }

Calculation 类函数

头文件 #pragma once #include \"StdAfx.h\" class CCalculation { public:

CCalculation(void); ~CCalculation(void);

static AcGePoint2d MiddlePoint(AcGePoint2d pt1,AcGePoint2d pt2); static AcGePoint3d MiddlePoint(AcGePoint3d pt1,AcGePoint3d pt2); };

源文件

#include \"StdAfx.h\" #include \"Calculation.h\"

CCalculation::CCalculation(void) { }

CCalculation::~CCalculation(void) { }

//计算两点连线中点的函数

AcGePoint2d CCalculation::MiddlePoint(AcGePoint2d pt1,AcGePoint2d pt2) {

AcGePoint2d pt;

pt[X]=(pt1[X]+pt2[X])/2; pt[Y]=(pt1[Y]+pt2[Y])/2; return pt; }

AcGePoint3d CCalculation::MiddlePoint(AcGePoint3d pt1,AcGePoint3d pt2) {

创建时间:2013/11/27 9:06:00

AcGePoint3d pt;

pt[X]=(pt1[X]+pt2[X])/2; pt[Y]=(pt1[Y]+pt2[Y])/2; pt[Z]=(pt1[Z]+pt2[Z])/2; return pt; }

2013/12/1

创建时间:2013/11/27 9:06:00

十、创建圆弧(“三点法”,“起点、圆心、终点法”,“起点、圆心、圆弧角度法”) 创建两个自定义类“Calculation”和“CreateEnt” CreateEnt类头文件

#include \"StdAfx.h\" class CreateEnt { public:

CreateEnt(void); ~CreateEnt(void);

static AcDbObjectId CreateArc(AcGePoint3d ptCenter,AcGeVector3d vec,double radius,double startAngle,double endAngle);

static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt);

static AcDbObjectId CreateArc(AcGePoint2d ptCenter,double radius,double startAngle,double endAngle);

//三点法创建圆弧函数声明

static AcDbObjectId CreateArc(AcGePoint2d ptStart,AcGePoint2d ptOnArc,AcGePoint2d ptEnd);

static AcDbObjectId CreateArc(AcGePoint2d ptStart,AcGePoint2d ptOnArc,AcGePoint2d ptEnd);

//起点、圆心、终点法创建圆弧

static AcDbObjectId CreateArcSCE(AcGePoint2d ptStart,AcGePoint2d ptCenter,AcGePoint2d ptEnd);

//起点、圆心、圆弧角度法创建圆

static AcDbObjectId CreateArc(AcGePoint2d ptStart, AcGePoint2d ptCenter,double angle); }; 源文件

AcDbObjectId CreateEnt::CreateArc(AcGePoint3d ptCenter,AcGeVector3d vec,double radius,double startAngle,double endAngle) {

AcDbArc *pArc=new AcDbArc(ptCenter,vec,radius,startAngle,endAngle); AcDbObjectId arcId;

arcId=CreateEnt::PostToModelSpace(pArc); return arcId; }

AcDbObjectId CreateEnt::PostToModelSpace(AcDbEntity *pEnt) {

AcDbBlockTable *pBlockTable;

acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead);

AcDbBlockTableRecord *pBlockTableRecord;

pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); AcDbObjectId entId;

pBlockTableRecord->appendAcDbEntity(entId,pEnt); pBlockTable->close();

2020/11/2 6:51:32 上午 Created by MShl

pBlockTableRecord->close(); pEnt->close(); return entId; } AcDbObjectId CreateEnt::CreateArc(AcGePoint2d ptCenter,double radius,double startAngle,double endAngle); { AcGeVector3d vec(0,0,1); return CreateEnt::AcDbArc(Calculation::Pt2dTo3d(ptCenter),vec,radius,startAngle,endAngle); } //三点创建圆弧函数 AcDbObjectId CreateEnt::CreateArc(AcGePoint2d ptStart,AcGePoint2d ptOnArc,AcGePoint2d ptEnd) { //使用几何类获得圆心、半径 AcGeCircArc2d geArc(ptStart,ptOnArc,ptEnd); AcGePoint2d ptCenter=geArc.center(); double radius=geArc.radius(); //计算起始和终止角度 AcGeVector2d vecStart(ptStart.x-ptCenter.x,ptStart.y-ptCenter.y); AcGeVector2d vecEnd(ptEnd.x-ptCenter.x,ptEnd.y-ptCenter.y); double StartAngle=vecStart.angle(); double EndAngle=vecEnd.angle(); return CreateEnt::CreateArc(ptCenter,radius,startAngle,endAngle); } //起点、圆心、半径创建圆弧函数 AcDbObjectId CreateEnt::CreateArcSCE(AcGePoint2d ptStart, AcGePoint2d ptCenter, AcGePoint2d ptEnd) { //计算半径 double radius=ptCenter.distanceTo(ptStart); //计算起点、终点角度 AcGeVector2d vecStart(ptStart.x-ptCenter.x,ptStart.y-ptCenter.y); AcGeVector2d vecEnd(ptEnd.x-ptCenter.x,ptEnd.y-ptCenter.y); double startAngle=vecStart.angle(); double endAngle=vecEnd.angle(); //创建圆弧 return CreateEnt::CreateArc(ptCenter,radius,startAngle,endAngle); } //起点、圆心、圆弧角度法创建圆弧函数 AcDbObjectId CreateEnt::CreateArc(AcGePoint2d ptStart, AcGePoint2d ptCenter, double angle) { //计算半径 double radius=ptCenter.distanceTo(ptStart); Comment [M9]: 此处不应有分号,类同 Comment [M10]: 不要漏写括号,下同 2020/11/2 6:51:32 上午 Created by MShl

//计算起点终点角度

AcGeVector2d vecStart(ptStart.x-ptCenter.x,ptStart.y-ptCenter.y); double startAngle=vecStart.angle(); double endAngle=startAngle+angle; //创建圆弧

return CreateEnt::CreateArc(ptCenter,radius,startAngle,endAngle); }

Calculation 类头 文 件 #pragma once #include \"StdAfx.h\" class Calculation { public:

Calculation(void); ~Calculation(void);

//添加将二维点转化为三维点的函数

static AcGePoint3d Pt2dTo3d(AcGePoint2d pt); //添加计算常量的值的函数static double PI(); }; 源文件

#include \"Calculation.h\"

Calculation::Calculation(void) { }

Calculation::~Calculation(void) { }

AcGePoint3d Calculation::Pt2dTo3d(AcGePoint2d pt) {

AcGePoint3d ptTemp(pt.x,pt.y,0); return ptTemp; }

double Calculation::PI() {

return 4*atan(1.0);

//atan是一个C语言的库函数,用来计算反正切函数的值 }

2020/11/2 6:51:32 上午 Created by MShl

Comment [M11]: 该处为二维点,不arxEntryPoint 函数 分别创建三个命令,用以实现用三种不同方法创建圆弧。 // - mshlCreateArc.sandianfa command (do not rename) //三点法创建圆弧 static void mshlCreateArcsandianfa(void) { // Add your code for command mshlCreateArc.sandianfa here AcGePoint2d pt1(100,200); AcGePoint2d pt2(150,250); AcGePoint2d pt3(200,300); AcDbObjectId arcId; arcId=CreateEnt::CreateArc(pt1,pt2,pt3); } 要定义成三维的参数,否则会提示“没有重载函数接收三个参数” // - mshlCreateArc.qiyuanzhong command (do not rename) //起点、圆心、终点法创建圆弧 static void mshlCreateArcqiyuanzhong(void) { // Add your code for command mshlCreateArc.qiyuanzhong here AcGePoint2d pt1(100,100); AcGePoint2d pt2(50,50); AcGePoint2d pt3(0,100); AcDbObjectId arcId; arcId=CreateEnt::CreateArc(pt1,pt2,pt3); } // - mshlCreateArc.qiyuanjiao command (do not rename) //起点、圆心、圆弧角度法创建圆弧 static void mshlCreateArcqiyuanjiao(void) { // Add your code for command mshlCreateArc.qiyuanjiao here AcGePoint2d pt1(0,100); AcGePoint2d pt2(50,50); AcDbObjectId arcId; arcId=CreateEnt::CreateArc(pt1,pt2,Calculation::PI()/2); } //若不想每个方法都添加一条命令,而是用一个命令创建三条圆弧 //则用下面的语句 //三点法 //AcGePoint2d ptStart(); //AcGePoint2d ptOnArc(); //AcGePoint2d ptEnd(); //CreateEnt::CreateArc(ptStart,ptOnArc,ptEnd); 2020/11/2 6:51:32 上午 Created by MShl

//起点、圆心、终点法 //ptStart.set(); //ptCenter.set(); //ptEnd.set(); //CreateEnt::CreateArc(ptStart,ptCenter,ptEnd); //起点、圆心、圆弧角度法 //ptStart.set(); //ptCenter.set(); //CreateEnt::CreateArc(ptStart,ptCenter,Calculation::PI()/2); //其中*****.set()是对前面已经出现过的变量的重置,即重新赋值语句。 } ; 重要函数AcGeVector2d类用来表示一个二维空间中的矢量,现阶段知它有的成员函数有.center()、 .radius()、.angle()(用来返回该矢量和X轴正半轴的以弧度表示的角度)。例如: AcGePoint2d pt1; AcGePoint2d pt2; AcGePoint2d pt3; AcGeVector2d geArc(pt1,pt2,pt3); AcGePoint2d ptCenter=geArc.Center(); double radius=geArc.radius(); AcGeVector2d Vec(pt1.x-ptCenter.x,pt1.y-ptCenter.y); double startAngle=vec.angle(); 12/2/2013 Comment [M12]: 表示由三点 pt1、pt2、pt3 构成的圆的圆心 Comment [M13]: 表示由三点 pt1、pt2、pt3 构成的圆的半径 Comment [M14]: 表示矢量 pt1 与 X 轴正半轴的夹角弧度 2020/11/2 6:51:32 上午 Created by MShl

十一、创建多段线 ObjectARX中提供了三种多段线的相关类:AcDbPolyline、AcDb2dPolyline、和AcDb3dPolyline。其中利用AutoCAD的内部命令可以创建AcDbPolyline和AcDb3dPolyline类的对象,用pLine创建的是轻量多段线(AcDbPolyline),用3dPolyline命令创建的对象是三维多段线(AcDb3dPolyline)。而AcDb2dPolyline并不常用。 创建轻量多段线和三维多段线的函数,直接封装AcDbPolyline和AcDb3dPolyline类的构造函数即可;创建正多边形、矩形、圆形和圆环,实际上都是创建了特殊形状的轻量多段线, 创建这些对象的关键都在于顶点和凸度的确定。 创建轻量多段线 程序框架:新建一个类CreateEnt用来封装构造函数。头文件 #pragma once #include \"StdAfx.h\" class CreateEnt { public: CreateEnt(void); ~CreateEnt(void); static AcDbObjectId CreatePolyline(AcGePoint2dArray points,double width=0); static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt); static AcDbObjectId CreatePolyline(AcGePoint2d ptStart,AcGePoint2d ptEnd,double width); }; 源文件 #include \"StdAfx.h\" #include \"CreateEnt.h\" Comment [M15]: 在函数声明中为width 参数设置了默认的实参值 0,这样可以减少该类函数被调用时的输入量,注意,不能同时在函数的声明和定义中指定默认参数值,一般可在声明中指定。 Comment [M16]: 定义顶点个数 Comment [M17]: 顶点个数为AcGePointdArray 类成员函数 length 返回该类的参数 points 数组长度。 Comment [M18]: 创建多段线第一步: 创建类的实例,以多段线顶点的个数作为参数调用AcDbPolyline::AcDbPolyline 函数 Comment [M19]: 第二步,添加顶点, 使用 AcDbPolyline::addVertexAt 函数将每个顶点添加到多段线中。 CreateEnt::CreateEnt(void) { }

CreateEnt::~CreateEnt(void) { } AcDbObjectId CreateEnt::CreatePolyline(AcGePoint2dArray points, double width) { int numVertices=points.length(); AcDbPolyline *pPoly=new AcDbPolyline(numVertices);

for(int i=0;iaddVertexAt(i,points.at(i),1,width,width); } AcDbObjectId polyId; polyId=CreateEnt::PostToModelSpace(pPoly); 创建时间:2020/11/2 6:51:32 上午

return polyId; } AcDbObjectId CreateEnt::PostToModelSpace(AcDbEntity *pEnt) { AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); AcDbObjectId entId; pBlockTableRecord->appendAcDbEntity(entId,pEnt); pBlockTable->close(); pBlockTableRecord->close(); pEnt->close(); return entId; } //创建包含一条半圆的多段线 AcDbObjectId CreateEnt::CreatePolyline(AcGePoint2d ptStart, AcGePoint2d ptEnd, double width) { AcGePoint2dArray points; points.append(ptStart); points.append(ptEnd); return CreateEnt::CreatePolyline(points,width); } Comment [M20]: 创建二维数组 Comment [M21]: append 为AcGePoint2dArray 类成员函数,用于先数组中添加一个二维点。另外两个成员函数 removeAt 用于从数组中删除指定的元素,length 用于返回数组的长度。 创建时间:2020/11/2 6:51:32 上午

十二、创建正多边形 上节已经说过,可以利用轻量多段线的构造函数创建正多边形。创建正多边形的输入参数为中心、边数、外接圆半径、旋转角度(弧度)和线宽。 程序框架: 创建三个自定义类CreateEnt、ModifyEnt、Calculation。 CreateEnt类头文件 #include \"StdAfx.h\" class CreateEnt { public: CreateEnt(void); ~CreateEnt(void); static AcDbObjectId CreatePolyline(AcGePoint2dArray points,double width=0); static AcDbObjectId PostToModelSpace(AcDbEntity *pEnt); static AcDbObjectId CreatePolyline(AcGePoint2d ptStart,AcGePoint2d ptEnd,double width); static AcDbObjectId CreatePolygon(AcGePoint2d ptCenter,int number,double radius,double rotation,double width); }; 源文件 #include \"CreateEnt.h\" #include \"calculation.h\" #include \"ModifyEnt.h\" CreateEnt::CreateEnt(void) { }

Comment [M22]: 创建仅包含一条直线的多段线,以备调用。 CreateEnt::~CreateEnt(void) { } AcDbObjectId CreateEnt::CreatePolyline(AcGePoint2dArray points, double width) { int numVertices=points.length(); AcDbPolyline *pPoly=new AcDbPolyline(numVertices);

for(int i=0;iaddVertexAt(i,points.at(i),0,width,width); } AcDbObjectId polyId; polyId=CreateEnt::PostToModelSpace(pPoly); return polyId; } AcDbObjectId CreateEnt::PostToModelSpace(AcDbEntity *pEnt) 创建时间:11/2/2020 6:51:32 上午

{ AcDbBlockTable *pBlockTable; acdbHostApplicationServices()->workingDatabase()- >getBlockTable(pBlockTable,AcDb::kForRead); AcDbBlockTableRecord *pBlockTableRecord; pBlockTable->getAt(ACDB_MODEL_SPACE,pBlockTableRecord,AcDb::kForWrite); AcDbObjectId entId; pBlockTableRecord->appendAcDbEntity(entId,pEnt); pBlockTable->close(); pBlockTableRecord->close(); pEnt->close(); return entId; }

Comment [M23]: Comment [M24]: 计算顶点位置 Comment [M25]: 根据顶点位置创建多段线。 Comment [M26]: Cast 是 ObjectARX 所有类的基类,该函数提供了一种安全的类型转换机制,使用acdbOpenAcDbEntity 能够得到一个指向 AcDbEntity 对象的指针 pEnt,使用 cast 就能实现将其转换为指向AcDbPolyline 对象的指针 pPoly Comment [M27]: 闭合多段线 Comment [M28]: 旋转多段线(可选亦可不选)。 //添加创建正多边形的函数 AcDbObjectId CreateEnt::CreatePolygon(AcGePoint2d ptCenter, int number, double radius, double rotation, double width) { AcGePoint2dArray points; double angle=2*calculation::PI()/(double)number; for(int i=0;isetClosed(Adesk::kTrue); } pEnt->close(); ModifyEnt::Rotate(polyId,ptCenter,rotation); return polyId; } Calculation类头文件 #include \"StdAfx.h\" 创建时间:11/2/2020 6:51:32 上午

class calculation { public:

calculation(void); ~calculation(void); static double PI();

//添加将二维点转化为三维点的函数

static AcGePoint3d Pt2dTo3d(AcGePoint2d pt); //角度转化为弧度

static double GtoR(double angle); };

源文件

#include \"calculation.h\"

calculation::calculation(void) { }

calculation::~calculation(void) { }

double calculation::PI() {

return 4*atan(1.0);

//atan是一个C语言的库函数,用来计算反正切函数的值 }

AcGePoint3d calculation::Pt2dTo3d(AcGePoint2d pt) {

AcGePoint3d ptTemp(pt.x,pt.y,0); return ptTemp; }

double calculation::GtoR(double angle) {

return angle*calculation::PI()/180; }

ModifyEnt类头文件

#include \"StdAfx.h\" class ModifyEnt { public:

ModifyEnt(void); ~ModifyEnt(void);

static Acad::ErrorStatus Rotate(AcDbObjectId entId,AcGePoint2d ptBase,double rotation);

创建时间:11/2/2020 6:51:32 上午

}; 源文件 #include \"ModifyEnt.h\" #include \"calculation.h\" ModifyEnt::ModifyEnt(void) { }

Comment [M29]: AcGeMatrix3d 类型是几何变换矩阵类,该类用于实体的几何变换,只要使用 setToScaling, 、( 缩 放 ) setToRotation 、( 旋 转 ) setToTranslation(移动)三个函数设置所要进行的变换,然后对所要变换 的实体执行 transformedBy 函数即可。 ModifyEnt::~ModifyEnt(void) { } Acad::ErrorStatus ModifyEnt::Rotate(AcDbObjectId entId, AcGePoint2d ptBase, double rotation) { AcGeMatrix3d xform; AcGeVector3d vec(0,0,1); xform.setToRotation(rotation,vec,calculation::Pt2dTo3d(ptBase));

AcDbEntity *pEnt; Acad::ErrorStatus es=acdbOpenObject(pEnt,entId,AcDb::kForWrite,false); pEnt->transformBy(xform); pEnt->close(); return es; } arxEntryPoint.cpp static void mshlCreatePolygonliubianxing(void) { // Add your code for command mshlCreatePolygon.Polygon here CreateEnt::CreatePolygon(AcGePoint2d::kOrigin,6,100,calculation::GtoR(30),0); } 创建时间:11/2/2020 6:51:32 上午

因篇幅问题不能全部显示,请点此查看更多更全内容