CAD图纸DWG就是一个数据库。个人觉得可以理解为一个”树形数据库“,包含了数据库、实体、容器、符号表、字典等等内容。这些内容又都可以称之为对象,包括数据库本身也可以称之为对象。
每一个DWG文件,都会包含:九个固定的符号表和一个有名对象字典。符号表,每个符号表只能存储特定类型的对象,字典则是一个通用的容器可以存储任何类型的对象。
对于符号表和有名对象词典的区别、用法,需要在使用的时候感受。用文字比较难表达。甚至DWG数据库中各对象的层次,也是需要通过实际的使用,在代码中去做以区分。
常用的对象及其调用关系:
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.ApplicationServices;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.DatabaseServices;
using DataTable = Autodesk.AutoCAD.DatabaseServices.DataTable;
//文档
Document doc = Application.DocumentManager.MdiActiveDocument;
//数据库对象
//两种方式
Database db = HostApplicationServices.WorkingDatabase;
Database db = Application.DocumentManager.MdiActiveDocument.Database;
//编辑器
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
//获得块id
ObjectId blockTableId = db.BlockTableId;
//打开一个事务
//使用using,当using结束时,整个using块中的代码被及时释放,减少资源的占用
using (Transaction tr = db.TransactionManager.StartTransaction())
{
//块表
BlockTable blockTable = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;
//块表记录
//根据块表获取块表记录,BlockTable[BlockTableRecord.ModelSpace]
BlockTableRecord record = tr.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
//创建一个实体(可以是引线、圆圈等等)
Entity entity = new Entity();
//向数据库
tr.AddNewlyCreateDBObject(entity, true);
//第一种选择集的使用方式
//getentity(string message),输入的字符串主要是做提示用,该字符串会在CAD下方的命令行中展示、也会在鼠标上有所提示
PromptEntityResult ent = ed.GetEntity("\n请选择一个引线");
MLeader mleader = tr.GetObject(ent.ObjectId, OpenMode.ForWrite, true) as MLeader;
//或者。tr.getobject的返回值类型即为Entity
Entity entity = tr.GetObject(ent.ObjectId, OpenMode.ForWrite, true);
//第二种选择集的使用方式
//定义好强制输入的类型
PromptEntityOptions peo = new PromptEntityOptions("\n请选择块:");
peo.SetRejectMessage("\n选择的必须是块");
peo.AddAllowedClass(typeof(BlockReference), false);
PromptEntityResult res = ed.GetEntity(peo);
//当找到了匹配的实体类型,则status即为OK
//打开源码可查:OK Other Naone Modeless Error Cancel Keyword
if (res.Status != PromptStatus.OK)
return null;
//属性块 //创建一个属性块的系列操作:
//首先在CAD图纸上创建一个名为norm的块
//然后通过blockTable["norm"]得到这个块的ObjectId
//新建一个块参照并设置插入点。类型为norm(块定义的名称即为块参照的类型)
PromptPointResult pt = ed.GetPoint("\n选取属性块生成位置:");
Point3d position = (Point3d)pt.Value;
BlockReference br = new BlockReference(position, blockTable["norm"]);
ed.WriteMessage("\n新创建的块参照是否为空? -> "+(br == null).ToString() + " 块参照名称:" + br.Name);
BlockTableRecord record = btrId.GetObject(OpenMode.ForRead) as BlockTableRecord;
//块参照id
//ObjectId brId = br.ObjectId;
ObjectId brId = space.AppendEntity(br);//把块参照添加到模型空间
//数据字典
DBDictionary DictForRead = tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
//操作结束之后,关闭事务
tr.Commit();
}
CAD中所有对象都放在这些容器对象中,符号表和有名对象字典都具有相同的功能——组织和管理CAD数据库中的对象
——即他们含有实体对象,但是可以通过文字字符串作为关键字对对象实体进行查询,并向这些容器中添加记录(记录即对象)、修改记录
符号表与字典的不同:符号表有九种,每种符号表只能存储特点类型的对象(如块表只能存储块表记录、层表只能记录层表记录),而字典则是一种通用容器,可存储任何类型的对象。(一般多是通过符号表操作对象)
块表 | 尺寸标注样式表 | 层表 | 线型表 | 应用程序注册表 | 文字样式表 | 用户坐标系表 | 视口表 | 视图表 |
---|---|---|---|---|---|---|---|---|
BlockTable | DimStyleTable | LayerTable | LinetypeTable | RegAppTable | TextStyleTable | UCSTable | ViewportTable | ViewTable |
根据以上代码可以直观的看到:API的最高层次是Application,其次是DocumentManager.MdiActiveDocument
Application对象是AutoCAD API对象模型的根对象,通过Application,用户可以访问主窗口以及任何打开的图形(dwg)。一旦用户获得了图形(dwg),就可以访问图形(dwg)中的对象。获得Application等同获得了进入CAD的权限。
例如:Application.DocumentManager,该对象允许对当前图形的访问,并允许用户创建、保存和打开图形文件。通过Application对象提供的其他特性可以使用:信息中心(InfoCenter)、主窗口(MainWindow)、状态栏(StatusBar)等等对象。主窗口API允许用户访问应用程序的名称、大小、位置和可见性等。(注:虽然说是做CAD二次开发,但是并不是仅仅在CAD中加入一个插件,利用CAD提供的API是可以重建一个新的、模仿AutoCAD的CAD应用的。这就是高层次API的用处)