Auto CAD二次开发——封装事务处理函数并绘制直线函数
上一篇博客中文章最后提出了我的一个疑问,这一篇就学习到了,果然我想到的问题开发者早就想到。在学习过程中很有必要进行思考。学如逆水行舟,不进则退。 愿自己不忘初心,坚持积累。
目录
1、基础知识储备(函数封装)
2、功能分析
2.1事务处理函数封装方式一
2.2事务处理函数封装方式二
2.3事务处理函数封装方式三
2.4事务处理函数封装方式四
1、基础知识储备(函数封装)
函数封装的核心意义在于将特定功能的代码块包装为独立单元,通过隐藏实现细节、暴露清晰接口,实现代码的复用(避免重复编写)、逻辑抽象(降低使用复杂度)、便于维护(修改一处即可影响所有调用)、支持模块化开发(拆分复杂任务,便于协作与测试),并降低代码耦合度(减少模块依赖),最终使代码更简洁、易扩展,是构建高质量程序的基础。
2、功能分析
本篇博客主要想实现函数的封装,减少后续代码量,便于调用,同时使用两点的方式绘制直线,和起始点、长度,与X轴正方向的角度方式绘制直线。
2.1事务处理函数封装方式一
新建类库AddEntityTool.cs(后续所有对实体操作的封装函数都在这个函数库中)。
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public static partial class AddEntityTool{/// <summary>/// 将图形对象添加到图形对象中/// </summary>/// <param name="db">图形数据库</param>/// <param name="ent">图形对象</param>/// <returns>图形的objectId</returns>public static ObjectId AddEntityToModelSpace(this Database db,Entity ent){//声明objectId,用于返回ObjectId entTd = ObjectId.Null;//开启事务处理using (Transaction trans = db.TransactionManager.StartTransaction()){//打开块表BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//打开快表记录BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);//加载直线到快表记录entTd = btr.AppendEntity(ent);//更新事务数据trans.AddNewlyCreatedDBObject(ent, true);//事务提交trans.Commit();}return entTd;}}
}
封装函数的调用
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public class LineClass{[CommandMethod("CreateLine")]public void CreateLine(){//声明图形数据库Database db = HostApplicationServices.WorkingDatabase;Line line1 = new Line(new Point3d(100, 100, 0), new Point3d(200, 100, 0));db.AddEntityToModelSpace(line1);}}
}

2.2事务处理函数封装方式二
如果一次建立多条直线,采用方式一需要多次打开事务处理函数,因此对该函数进行重载,一次可以处理多条数据。
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public static partial class AddEntityTool{/// <summary>/// 将图形对象添加到图形对象中/// </summary>/// <param name="db">图形数据库</param>/// <param name="ent">图形对象,可变参数</param>/// <returns>图形的objectId,数组返回</returns>public static ObjectId[] AddEntityToModelSpace(this Database db, params Entity[] ent){//声明objectId,用于返回ObjectId[] entTd = new ObjectId[ent.Length];//开启事务处理using (Transaction trans = db.TransactionManager.StartTransaction()){//打开块表BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//打开快表记录BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);for (int i = 0; i < ent.Length; i++){//加载直线到快表记录entTd[i] = btr.AppendEntity(ent[i]);//更新事务数据trans.AddNewlyCreatedDBObject(ent[i], true);}//事务提交trans.Commit();}return entTd;}}
}
封装函数的调用
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public class LineClass{[CommandMethod("CreateLine")]public void CreateLine(){//声明图形数据库Database db = HostApplicationServices.WorkingDatabase;Line line2 = new Line(new Point3d(200, 200, 0), new Point3d(200, 300, 0));Line line3 = new Line(new Point3d(200, 300, 0), new Point3d(200, 100, 0));Line line4 = new Line(new Point3d(200, 100, 0), new Point3d(100, 100, 0));db.AddEntityToModelSpace(db, line2, line3, line4);}}
}
图中可能看到两条直线,原因是有两条存在部分重合,这里我不进行更改,读者看到以后不要有疑惑。

2.3事务处理函数封装方式三
采用以上两种方式创建直线均需要事先声明定义直线,采用第三种封装方式只需给出两个点即可。其实方法三调用方法一。
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public static partial class AddEntityTool{/// <summary>/// 将图形对象添加到图形对象中/// </summary>/// <param name="db">图形数据库</param>/// <param name="ent">图形对象</param>/// <returns>图形的objectId</returns>public static ObjectId AddEntityToModelSpace(this Database db,Entity ent){//声明objectId,用于返回ObjectId entTd = ObjectId.Null;//开启事务处理using (Transaction trans = db.TransactionManager.StartTransaction()){//打开块表BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//打开快表记录BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);//加载直线到快表记录entTd = btr.AppendEntity(ent);//更新事务数据trans.AddNewlyCreatedDBObject(ent, true);//事务提交trans.Commit();}return entTd;}/// <summary>/// 两点绘制直线/// </summary>/// <param name="db">图形数据库</param>/// <param name="startPoint">起点坐标</param>/// <param name="endPoint">终点坐标</param>/// <returns>图形的objectId</returns>public static ObjectId AddEntityToModelSpace(this Database db, Point3d startPoint, Point3d endPoint){return db.AddEntityToModelSpace(new Line(startPoint, endPoint));}}
}
封装函数的调用
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public class LineClass{[CommandMethod("CreateLine")]public void CreateLine(){//声明图形数据库Database db = HostApplicationServices.WorkingDatabase;db.AddEntityToModelSpace(new Point3d(100, 100, 0), new Point3d(200, 100, 0));}}
}

2.4事务处理函数封装方式四
采用一个起点、长度和角度的方式创建直线。其实也是用勾股定理设置起点和终点进行绘制直线。
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public static partial class AddEntityTool{/// <summary>/// 将图形对象添加到图形对象中/// </summary>/// <param name="db">图形数据库</param>/// <param name="ent">图形对象</param>/// <returns>图形的objectId</returns>public static ObjectId AddEntityToModelSpace(this Database db,Entity ent){//声明objectId,用于返回ObjectId entTd = ObjectId.Null;//开启事务处理using (Transaction trans = db.TransactionManager.StartTransaction()){//打开块表BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);//打开快表记录BlockTableRecord btr = (BlockTableRecord)trans.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForWrite);//加载直线到快表记录entTd = btr.AppendEntity(ent);//更新事务数据trans.AddNewlyCreatedDBObject(ent, true);//事务提交trans.Commit();}return entTd;}/// <summary>/// 起点、终点、角度绘制直线/// </summary>/// <param name="db">图形数据库</param>/// <param name="startPoint">起点坐标</param>/// <param name="length">直线的长度</param>/// <param name="degree">与X轴正方向的夹角</param>/// <returns>图形的objectId</returns>public static ObjectId AddEntityToModelSpace(this Database db, Point3d startPoint, Double length, Double degree){//计算终点坐标double endPointX = startPoint.X + length * Math.Cos(degree.DegreeToAngle());double endPointY = startPoint.Y + length * Math.Sin(degree.DegreeToAngle());Point3d endPoint = new Point3d(endPointX, endPointY, 0);return db.AddEntityToModelSpace(new Line(startPoint, endPoint));}}
}
封装函数的调用
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;namespace CAD_CreateLine
{public class LineClass{[CommandMethod("CreateLine")]public void CreateLine(){//声明图形数据库Database db = HostApplicationServices.WorkingDatabase;db.AddEntityToModelSpace(new Point3d(400, 400, 0), 200, 60);}}
}

温馨提示:在 CAD 二次开发中,核心价值在于 “扩展” 而非 “重复创造”。官方已经提供的基础功能 —— 比如绘制单条直线、单个圆等基础图形工具,早已经过严谨打磨,无需我们再做重复开发。我们的精力应聚焦于 “扩展”:比如,当业务需要批量生成 100 条按特定规律排列的直线(如等距分布、随路径变化的倾斜直线),或是一键绘制 100 个符合工程标准的三角形(如按坐标矩阵排列、带角度偏移的全等三角形),这些超出基础工具范畴的批量操作、定制化逻辑、场景化功能,才是二次开发的发力点。简单来说,我们不是重做 “画一条线” 的工具,而是打造 “按需求画一百条线” 的解决方案;不是复刻 “画一个三角形” 的功能,而是构建 “按规则生成百个三角形” 的高效工具。这种基于现有基础的延伸与拓展,才能真正解决实际场景中的复杂问题,让 CAD 工具更贴合具体业务需求。
