我是建筑暖通专业的,陆陆续续学习二次开发4个月,为自己做了一个修改备注的插件。主要应用于施工图后期,对一些修改的地方进行打圈并用引线到指定位置,方便给其它专业提资。
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Data.Common;
using System.Reflection;
using System.Xml.Linq;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using Exception = Autodesk.AutoCAD.Runtime.Exception;
namespace 修改标注
{
public class Class1
{
private static Point3d py = Point3d.Origin;
double xxhight = 1000;
int colorIndex = 140;
int SegmentValue = 20; // 每边分成20段,可以调整这个值改变云线密度
double bulgeValue = 0.5; // 凸度值,可以调整这个值改变云线的弯曲程度
[CommandMethod("XX1")]
public void XX1()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
//备份正交模式
object originalOrthoMode = Application.GetSystemVariable("ORTHOMODE");
try
{
//关闭正交模式
Application.SetSystemVariable("ORTHOMODE", 0);
Point3d p1 = new Point3d();
Point3d p3 = new Point3d();
//获取矩形第一个角点
bool pointSelected = false;
while (!pointSelected)
{
PromptPointOptions ppo1 = new PromptPointOptions("\n请指定第一个点或[字高(H)颜色(C)分段数(S)凸度(B)]");
ppo1.Keywords.Add("H");
ppo1.Keywords.Add("C");
ppo1.Keywords.Add("S");
ppo1.Keywords.Add("B");
ppo1.AppendKeywordsToMessage = false;
PromptPointResult ppr1 = ed.GetPoint(ppo1);
if (ppr1.Status == PromptStatus.Keyword)
{
switch (ppr1.StringResult)
{
case "H"://设置字高
PromptDoubleOptions pdo_h = new PromptDoubleOptions("\n请输入修改说明字体高度(当前字高:" + xxhight + ")");
pdo_h.AllowNone = true;
pdo_h.AllowNegative = false;
pdo_h.AllowZero = false;
pdo_h.DefaultValue = xxhight;
PromptDoubleResult pdr_h = ed.GetDouble(pdo_h);
if (pdr_h.Status == PromptStatus.Cancel)
{
// 字体设置取消,退出
return;
}
if (pdr_h.Status == PromptStatus.None) ed.WriteMessage("使用原字高:");
if (pdr_h.Status == PromptStatus.OK) xxhight = pdr_h.Value;
break; // 跳出switch,继续while循环
case "C"://设置颜色
PromptIntegerOptions pio_c = new PromptIntegerOptions("\n请输入颜色值(当前颜色值:" + colorIndex + ")");
pio_c.AllowNone = true;
pio_c.DefaultValue = colorIndex;
pio_c.AllowNegative = false; // 禁止负数
pio_c.LowerLimit = 0; // 最小0
pio_c.UpperLimit = 256; // 最大256
PromptIntegerResult pir_c = ed.GetInteger(pio_c);
if (pir_c.Status == PromptStatus.Cancel)
{
// 颜色设置取消,退出
return;
}
if (pir_c.Status == PromptStatus.None) ed.WriteMessage("使用原颜色:");
if (pir_c.Status == PromptStatus.OK) colorIndex = pir_c.Value;
break;
case "S"://设置云线每边分段数
PromptIntegerOptions pio_s = new PromptIntegerOptions("\n请输入云线每边分段数(当前分段数:" + SegmentValue + ")");
pio_s.AllowNone = true;
pio_s.DefaultValue = SegmentValue;
pio_s.AllowNegative = false; // 禁止负数
pio_s.LowerLimit = 3; // 最小3
pio_s.UpperLimit = 100; // 最大100
PromptIntegerResult pir_s = ed.GetInteger(pio_s);
if (pir_s.Status == PromptStatus.Cancel)
{
return;
}
if (pir_s.Status == PromptStatus.None) ed.WriteMessage("使用原分段数:");
if (pir_s.Status == PromptStatus.OK) SegmentValue = pir_s.Value;
break;
case "B"://设置云线凸度值
bool validBulge = false;
while (!validBulge)
{
PromptDoubleOptions pdo_b = new PromptDoubleOptions("\n请输入云线凸度(-1.0~1.0之间的数)(当前凸度:" + bulgeValue + ")");
pdo_b.AllowNone = true;
pdo_b.DefaultValue = bulgeValue;
PromptDoubleResult pdr_b = ed.GetDouble(pdo_b);
if (pdr_b.Status == PromptStatus.Cancel)
{
return;
}
if (pdr_b.Status == PromptStatus.None)
{
ed.WriteMessage("使用当前凸度:");
validBulge = true;
}
if (pdr_b.Status == PromptStatus.OK)
{
if (pdr_b.Value < -1 || pdr_b.Value > 1) ed.WriteMessage("\n错误:凸度一般在-1~1之间!");
else
{
bulgeValue = pdr_b.Value;
validBulge = true;
}
}
}
break;
}
}
else if (ppr1.Status == PromptStatus.OK)
{
p1 = ppr1.Value;
pointSelected = true; // 退出循环
}
else
{
// 用户取消或其他状态
return;
}
}
//获取矩形第二个角触点
PromptPointOptions ppo = new PromptPointOptions("\n请指第二个点");
ppo.AllowNone = true;
ppo.BasePoint = p1;
ppo.UseBasePoint = true;
PromptPointResult ppr2 = ed.GetPoint(ppo);
if (ppr2.Status != PromptStatus.OK) return;
p3 = ppr2.Value;
//恢复正交模式
Application.SetSystemVariable("ORTHOMODE", originalOrthoMode);
//进行坐标点计算并把UCS坐标转为WCS坐标
double x1 = p1.X;
double y1 = p1.Y;
double x2 = p3.X;
double y2 = p3.Y;
Point3d p2 = new Point3d(x1, y2, 0);
Point3d p4 = new Point3d(x2, y1, 0);
Point3d wcsp1 = UcsToWcs(p1);
Point3d wcsp2 = UcsToWcs(p2);
Point3d wcsp3 = UcsToWcs(p3);
Point3d wcsp4 = UcsToWcs(p4);
Point2d p2dp1 = new Point2d(wcsp1.X, wcsp1.Y);
Point2d p2dp2 = new Point2d(wcsp2.X, wcsp2.Y);
Point2d p2dp3 = new Point2d(wcsp3.X, wcsp3.Y);
Point2d p2dp4 = new Point2d(wcsp4.X, wcsp4.Y);
//创建多段线(矩形)
Polyline pL = new Polyline();
pL.AddVertexAt(0, p2dp1, 0, 0, 0);
pL.AddVertexAt(1, p2dp2, 0, 0, 0);
pL.AddVertexAt(2, p2dp3, 0, 0, 0);
pL.AddVertexAt(3, p2dp4, 0, 0, 0);
double pLlenght = pL.Length;
Polyline revcloud = CreateCloudPolyline(p2dp1, p2dp2, p2dp3, p2dp4, pLlenght);//创建云线
//日期为命名创建图层,设置颜色及非打印
string fileName = "ACS-修改" + DateTime.Now.ToString("yyyyMMdd");
Addlayer(fileName, colorIndex, false);
//设置矩形的图层并在模型画出
revcloud.Layer = fileName;
revcloud.ColorIndex = colorIndex;
AddEntityToModelSpace(revcloud);
//画引出线,由矩形中心到引出点
PromptPointResult ppr3 = GetPoint2(ed, "\n请指定引出点位置");//由ed.GetPoint2("\n请指定引出点位置")改为GetPoint2(ed, "\n请指定引出点位置")
if (ppr3.Status == PromptStatus.Cancel) return;
if (ppr3.Status == PromptStatus.OK)
{
py = UcsToWcs(ppr3.Value);
}
Point3d center = new Point3d((p2dp1.X + p2dp3.X) / 2, (p2dp1.Y + p2dp3.Y) / 2, 0);
Line line = new Line(center, py);
line.Layer = fileName;
line.ColorIndex = colorIndex;
AddEntityToModelSpace(line);
Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
double ucsRotation = GetUcsRotationAngle(ucsMatrix);
if (ppr3.Status == PromptStatus.OK)
{
DBText dbText = new DBText
{
TextString = "修改说明",
Position = py,
Height = xxhight,
Layer = fileName,
ColorIndex=colorIndex,
Rotation = ucsRotation // 旋转抵消UCS旋转
};
AddEntityToModelSpace(dbText);
}
}
catch (Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
}
}
//创建云线多段线
private Polyline CreateCloudPolyline(Point2d p1, Point2d p2, Point2d p3, Point2d p4, double lenght)
{
Polyline cloud = new Polyline();
cloud.Closed = true;
// 云线参数:每边分段数和凸度
// 四个边:p1->p2, p2->p3, p3->p4, p4->p1
Point2d[] corners = new Point2d[] { p1, p2, p3, p4 };
int vertexIndex = 0;
for (int side = 0; side < 4; side++)
{
Point2d start = corners[side];
Point2d end = corners[(side + 1) % 4];
for (int seg = 0; seg <= SegmentValue; seg++)
{
double t = (double)seg / SegmentValue;
double x = start.X + (end.X - start.X) * t;
double y = start.Y + (end.Y - start.Y) * t;
// 添加顶点
cloud.AddVertexAt(vertexIndex, new Point2d(x, y), 0, 0, lenght / 500);
// 每隔一个点设置凸度,创建云线效果
if (seg < SegmentValue && seg % 2 == 0)
{
cloud.SetBulgeAt(vertexIndex, bulgeValue);
}
else if (seg < SegmentValue)
{
cloud.SetBulgeAt(vertexIndex, -bulgeValue);
}
vertexIndex++;
}
}
return cloud;
}
public static void Addlayer(string name, int color, bool isTure)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
if (!lt.Has(name))//判断是否已有该图层名字,如有会出错
{
lt.UpgradeOpen();
LayerTableRecord layerTableRecord = new LayerTableRecord()
{
Name = name,
Color = Color.FromColorIndex(ColorMethod.ByAci, (short)color),
IsFrozen = false,//非冻结
IsOff = false,
IsPlottable = isTure
};
lt.Add(layerTableRecord);
trans.AddNewlyCreatedDBObject(layerTableRecord, true);
trans.Commit();
}
}
}
public static void AddEntityToModelSpace(Entity entity)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
//开启事务处理
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);
//加直线到块表记录
btr.AppendEntity(entity);
//更新数据
trans.AddNewlyCreatedDBObject(entity, true);
//事务提交
trans.Commit();
}
}
// 将点从UCS转换到WCS
public static Point3d UcsToWcs(Point3d ucsPoint)
{
Matrix3d ucsMatrix = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
return ucsPoint.TransformBy(ucsMatrix);
}
public static PromptPointResult GetPoint2(Editor ed, string promptStr)
{
//声明一个获取点的提示类
PromptPointOptions ppo = new PromptPointOptions(promptStr);
ppo.AllowNone = true;
return ed.GetPoint(ppo);
}
private double GetUcsRotationAngle(Matrix3d ucsMatrix)
{
// 提取UCS的X轴向量
Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
// 计算X轴与WCS X轴(1,0,0)的夹角
Vector3d wcsXAxis = new Vector3d(1, 0, 0);
double angle = wcsXAxis.GetAngleTo(xAxis, new Vector3d(0, 0, 1));
return angle;
}
}
}
网友答: 没有用IFox
网友答:
簡單的用編譯器優化了下語法,嘗試用編譯器代碼提示來優化代碼格式哦

另,關於關鍵字直接寫明碼太ugly了,可以看下驚佬寫的這個,里面有關於enum枚舉的寫法來優化關鍵字處理!
https://bbs.mjtd.com/thread-190868-1-1.html网友答:
谢谢你的建议,这确实有点鸡肋,后续改进网友答: 大神新年快乐,2026马上发财
网友答:
这个不错,顶起来网友答:
谢谢分享,新年快乐!网友答:
C#基本都还没搞明白,IFOX太高级了
网友答:
你能写出来这个已经可以去看IFox的test了网友答: 怎么使用呢?网友答:
加载我附件里面的DLL,使用XX1命令,然后根据提示就可以了
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.Colors;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using System;
using System.Data.Common;
using System.Reflection;
using System.Xml.Linq;
using Application = Autodesk.AutoCAD.ApplicationServices.Application;
using Exception = Autodesk.AutoCAD.Runtime.Exception;
namespace 修改标注
{
public class Class1
{
private static Point3d py = Point3d.Origin;
double xxhight = 1000;
int colorIndex = 140;
int SegmentValue = 20; // 每边分成20段,可以调整这个值改变云线密度
double bulgeValue = 0.5; // 凸度值,可以调整这个值改变云线的弯曲程度
[CommandMethod("XX1")]
public void XX1()
{
Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
//备份正交模式
object originalOrthoMode = Application.GetSystemVariable("ORTHOMODE");
try
{
//关闭正交模式
Application.SetSystemVariable("ORTHOMODE", 0);
Point3d p1 = new Point3d();
Point3d p3 = new Point3d();
//获取矩形第一个角点
bool pointSelected = false;
while (!pointSelected)
{
PromptPointOptions ppo1 = new PromptPointOptions("\n请指定第一个点或[字高(H)颜色(C)分段数(S)凸度(B)]");
ppo1.Keywords.Add("H");
ppo1.Keywords.Add("C");
ppo1.Keywords.Add("S");
ppo1.Keywords.Add("B");
ppo1.AppendKeywordsToMessage = false;
PromptPointResult ppr1 = ed.GetPoint(ppo1);
if (ppr1.Status == PromptStatus.Keyword)
{
switch (ppr1.StringResult)
{
case "H"://设置字高
PromptDoubleOptions pdo_h = new PromptDoubleOptions("\n请输入修改说明字体高度(当前字高:" + xxhight + ")");
pdo_h.AllowNone = true;
pdo_h.AllowNegative = false;
pdo_h.AllowZero = false;
pdo_h.DefaultValue = xxhight;
PromptDoubleResult pdr_h = ed.GetDouble(pdo_h);
if (pdr_h.Status == PromptStatus.Cancel)
{
// 字体设置取消,退出
return;
}
if (pdr_h.Status == PromptStatus.None) ed.WriteMessage("使用原字高:");
if (pdr_h.Status == PromptStatus.OK) xxhight = pdr_h.Value;
break; // 跳出switch,继续while循环
case "C"://设置颜色
PromptIntegerOptions pio_c = new PromptIntegerOptions("\n请输入颜色值(当前颜色值:" + colorIndex + ")");
pio_c.AllowNone = true;
pio_c.DefaultValue = colorIndex;
pio_c.AllowNegative = false; // 禁止负数
pio_c.LowerLimit = 0; // 最小0
pio_c.UpperLimit = 256; // 最大256
PromptIntegerResult pir_c = ed.GetInteger(pio_c);
if (pir_c.Status == PromptStatus.Cancel)
{
// 颜色设置取消,退出
return;
}
if (pir_c.Status == PromptStatus.None) ed.WriteMessage("使用原颜色:");
if (pir_c.Status == PromptStatus.OK) colorIndex = pir_c.Value;
break;
case "S"://设置云线每边分段数
PromptIntegerOptions pio_s = new PromptIntegerOptions("\n请输入云线每边分段数(当前分段数:" + SegmentValue + ")");
pio_s.AllowNone = true;
pio_s.DefaultValue = SegmentValue;
pio_s.AllowNegative = false; // 禁止负数
pio_s.LowerLimit = 3; // 最小3
pio_s.UpperLimit = 100; // 最大100
PromptIntegerResult pir_s = ed.GetInteger(pio_s);
if (pir_s.Status == PromptStatus.Cancel)
{
return;
}
if (pir_s.Status == PromptStatus.None) ed.WriteMessage("使用原分段数:");
if (pir_s.Status == PromptStatus.OK) SegmentValue = pir_s.Value;
break;
case "B"://设置云线凸度值
bool validBulge = false;
while (!validBulge)
{
PromptDoubleOptions pdo_b = new PromptDoubleOptions("\n请输入云线凸度(-1.0~1.0之间的数)(当前凸度:" + bulgeValue + ")");
pdo_b.AllowNone = true;
pdo_b.DefaultValue = bulgeValue;
PromptDoubleResult pdr_b = ed.GetDouble(pdo_b);
if (pdr_b.Status == PromptStatus.Cancel)
{
return;
}
if (pdr_b.Status == PromptStatus.None)
{
ed.WriteMessage("使用当前凸度:");
validBulge = true;
}
if (pdr_b.Status == PromptStatus.OK)
{
if (pdr_b.Value < -1 || pdr_b.Value > 1) ed.WriteMessage("\n错误:凸度一般在-1~1之间!");
else
{
bulgeValue = pdr_b.Value;
validBulge = true;
}
}
}
break;
}
}
else if (ppr1.Status == PromptStatus.OK)
{
p1 = ppr1.Value;
pointSelected = true; // 退出循环
}
else
{
// 用户取消或其他状态
return;
}
}
//获取矩形第二个角触点
PromptPointOptions ppo = new PromptPointOptions("\n请指第二个点");
ppo.AllowNone = true;
ppo.BasePoint = p1;
ppo.UseBasePoint = true;
PromptPointResult ppr2 = ed.GetPoint(ppo);
if (ppr2.Status != PromptStatus.OK) return;
p3 = ppr2.Value;
//恢复正交模式
Application.SetSystemVariable("ORTHOMODE", originalOrthoMode);
//进行坐标点计算并把UCS坐标转为WCS坐标
double x1 = p1.X;
double y1 = p1.Y;
double x2 = p3.X;
double y2 = p3.Y;
Point3d p2 = new Point3d(x1, y2, 0);
Point3d p4 = new Point3d(x2, y1, 0);
Point3d wcsp1 = UcsToWcs(p1);
Point3d wcsp2 = UcsToWcs(p2);
Point3d wcsp3 = UcsToWcs(p3);
Point3d wcsp4 = UcsToWcs(p4);
Point2d p2dp1 = new Point2d(wcsp1.X, wcsp1.Y);
Point2d p2dp2 = new Point2d(wcsp2.X, wcsp2.Y);
Point2d p2dp3 = new Point2d(wcsp3.X, wcsp3.Y);
Point2d p2dp4 = new Point2d(wcsp4.X, wcsp4.Y);
//创建多段线(矩形)
Polyline pL = new Polyline();
pL.AddVertexAt(0, p2dp1, 0, 0, 0);
pL.AddVertexAt(1, p2dp2, 0, 0, 0);
pL.AddVertexAt(2, p2dp3, 0, 0, 0);
pL.AddVertexAt(3, p2dp4, 0, 0, 0);
double pLlenght = pL.Length;
Polyline revcloud = CreateCloudPolyline(p2dp1, p2dp2, p2dp3, p2dp4, pLlenght);//创建云线
//日期为命名创建图层,设置颜色及非打印
string fileName = "ACS-修改" + DateTime.Now.ToString("yyyyMMdd");
Addlayer(fileName, colorIndex, false);
//设置矩形的图层并在模型画出
revcloud.Layer = fileName;
revcloud.ColorIndex = colorIndex;
AddEntityToModelSpace(revcloud);
//画引出线,由矩形中心到引出点
PromptPointResult ppr3 = GetPoint2(ed, "\n请指定引出点位置");//由ed.GetPoint2("\n请指定引出点位置")改为GetPoint2(ed, "\n请指定引出点位置")
if (ppr3.Status == PromptStatus.Cancel) return;
if (ppr3.Status == PromptStatus.OK)
{
py = UcsToWcs(ppr3.Value);
}
Point3d center = new Point3d((p2dp1.X + p2dp3.X) / 2, (p2dp1.Y + p2dp3.Y) / 2, 0);
Line line = new Line(center, py);
line.Layer = fileName;
line.ColorIndex = colorIndex;
AddEntityToModelSpace(line);
Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
double ucsRotation = GetUcsRotationAngle(ucsMatrix);
if (ppr3.Status == PromptStatus.OK)
{
DBText dbText = new DBText
{
TextString = "修改说明",
Position = py,
Height = xxhight,
Layer = fileName,
ColorIndex=colorIndex,
Rotation = ucsRotation // 旋转抵消UCS旋转
};
AddEntityToModelSpace(dbText);
}
}
catch (Exception ex)
{
ed.WriteMessage($"\n错误: {ex.Message}");
}
}
//创建云线多段线
private Polyline CreateCloudPolyline(Point2d p1, Point2d p2, Point2d p3, Point2d p4, double lenght)
{
Polyline cloud = new Polyline();
cloud.Closed = true;
// 云线参数:每边分段数和凸度
// 四个边:p1->p2, p2->p3, p3->p4, p4->p1
Point2d[] corners = new Point2d[] { p1, p2, p3, p4 };
int vertexIndex = 0;
for (int side = 0; side < 4; side++)
{
Point2d start = corners[side];
Point2d end = corners[(side + 1) % 4];
for (int seg = 0; seg <= SegmentValue; seg++)
{
double t = (double)seg / SegmentValue;
double x = start.X + (end.X - start.X) * t;
double y = start.Y + (end.Y - start.Y) * t;
// 添加顶点
cloud.AddVertexAt(vertexIndex, new Point2d(x, y), 0, 0, lenght / 500);
// 每隔一个点设置凸度,创建云线效果
if (seg < SegmentValue && seg % 2 == 0)
{
cloud.SetBulgeAt(vertexIndex, bulgeValue);
}
else if (seg < SegmentValue)
{
cloud.SetBulgeAt(vertexIndex, -bulgeValue);
}
vertexIndex++;
}
}
return cloud;
}
public static void Addlayer(string name, int color, bool isTure)
{
Database db = HostApplicationServices.WorkingDatabase;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
if (!lt.Has(name))//判断是否已有该图层名字,如有会出错
{
lt.UpgradeOpen();
LayerTableRecord layerTableRecord = new LayerTableRecord()
{
Name = name,
Color = Color.FromColorIndex(ColorMethod.ByAci, (short)color),
IsFrozen = false,//非冻结
IsOff = false,
IsPlottable = isTure
};
lt.Add(layerTableRecord);
trans.AddNewlyCreatedDBObject(layerTableRecord, true);
trans.Commit();
}
}
}
public static void AddEntityToModelSpace(Entity entity)
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
//开启事务处理
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);
//加直线到块表记录
btr.AppendEntity(entity);
//更新数据
trans.AddNewlyCreatedDBObject(entity, true);
//事务提交
trans.Commit();
}
}
// 将点从UCS转换到WCS
public static Point3d UcsToWcs(Point3d ucsPoint)
{
Matrix3d ucsMatrix = Application.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
return ucsPoint.TransformBy(ucsMatrix);
}
public static PromptPointResult GetPoint2(Editor ed, string promptStr)
{
//声明一个获取点的提示类
PromptPointOptions ppo = new PromptPointOptions(promptStr);
ppo.AllowNone = true;
return ed.GetPoint(ppo);
}
private double GetUcsRotationAngle(Matrix3d ucsMatrix)
{
// 提取UCS的X轴向量
Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
// 计算X轴与WCS X轴(1,0,0)的夹角
Vector3d wcsXAxis = new Vector3d(1, 0, 0);
double angle = wcsXAxis.GetAngleTo(xAxis, new Vector3d(0, 0, 1));
return angle;
}
}
}
网友答: 没有用IFox
网友答:
簡單的用編譯器優化了下語法,嘗試用編譯器代碼提示來優化代碼格式哦
- using Acaop = Autodesk.AutoCAD.ApplicationServices.Core.Application;
- namespace 修改标注;
- public class Class1
- {
- private static Point3d _py = Point3d.Origin;
- private double _xxHeight = 1000;
- private int _colorIndex = 140;
- private int _segmentValue = 20; // 每边分成20段,可以调整这个值改变云线密度
- private double _bulgeValue = 0.5; // 凸度值,可以调整这个值改变云线的弯曲程度
- [CommandMethod(nameof(Xx1))]
- public void Xx1()
- {
- Editor ed = Acaop.DocumentManager.MdiActiveDocument.Editor;
- //备份正交模式
- object originalOrthoMode = Acaop.GetSystemVariable("ORTHOMODE");
- try
- {
- //关闭正交模式
- Acaop.SetSystemVariable("ORTHOMODE", 0);
- Point3d p1 = new Point3d();
- //获取矩形第一个角点
- bool pointSelected = false;
- while (!pointSelected)
- {
- PromptPointOptions ppo1 = new PromptPointOptions("\n请指定第一个点或[字高(H)颜色(C)分段数(S)凸度(B)]");
- ppo1.Keywords.Add("H");
- ppo1.Keywords.Add("C");
- ppo1.Keywords.Add("S");
- ppo1.Keywords.Add("B");
- ppo1.AppendKeywordsToMessage = false;
- PromptPointResult ppr1 = ed.GetPoint(ppo1);
- if (ppr1.Status == PromptStatus.Keyword)
- {
- switch (ppr1.StringResult)
- {
- case "H": //设置字高
- PromptDoubleOptions pdoH = new PromptDoubleOptions(
- "\n请输入修改说明字体高度(当前字高:" + _xxHeight + ")"
- )
- {
- AllowNone = true,
- AllowNegative = false,
- AllowZero = false,
- DefaultValue = _xxHeight,
- };
- PromptDoubleResult pdrH = ed.GetDouble(pdoH);
- if (pdrH.Status == PromptStatus.Cancel)
- {
- // 字体设置取消,退出
- return;
- }
- if (pdrH.Status == PromptStatus.None)
- ed.WriteMessage("使用原字高:");
- if (pdrH.Status == PromptStatus.OK)
- _xxHeight = pdrH.Value;
- break; // 跳出switch,继续while循环
- case "C": //设置颜色
- PromptIntegerOptions pioC = new PromptIntegerOptions(
- "\n请输入颜色值(当前颜色值:" + _colorIndex + ")"
- )
- {
- AllowNone = true,
- DefaultValue = _colorIndex,
- AllowNegative = false, // 禁止负数
- LowerLimit = 0, // 最小0
- UpperLimit = 256, // 最大256
- };
- PromptIntegerResult pirC = ed.GetInteger(pioC);
- if (pirC.Status == PromptStatus.Cancel)
- {
- // 颜色设置取消,退出
- return;
- }
- if (pirC.Status == PromptStatus.None)
- ed.WriteMessage("使用原颜色:");
- if (pirC.Status == PromptStatus.OK)
- _colorIndex = pirC.Value;
- break;
- case "S": //设置云线每边分段数
- PromptIntegerOptions pioS = new PromptIntegerOptions(
- "\n请输入云线每边分段数(当前分段数:" + _segmentValue + ")"
- )
- {
- AllowNone = true,
- DefaultValue = _segmentValue,
- AllowNegative = false, // 禁止负数
- LowerLimit = 3, // 最小3
- UpperLimit = 100, // 最大100
- };
- PromptIntegerResult pirS = ed.GetInteger(pioS);
- if (pirS.Status == PromptStatus.Cancel)
- {
- return;
- }
- if (pirS.Status == PromptStatus.None)
- ed.WriteMessage("使用原分段数:");
- if (pirS.Status == PromptStatus.OK)
- _segmentValue = pirS.Value;
- break;
- case "B": //设置云线凸度值
- bool validBulge = false;
- while (!validBulge)
- {
- PromptDoubleOptions pdoB = new PromptDoubleOptions(
- "\n请输入云线凸度(-1.0~1.0之间的数)(当前凸度:" + _bulgeValue + ")"
- )
- {
- AllowNone = true,
- DefaultValue = _bulgeValue,
- };
- PromptDoubleResult pdrB = ed.GetDouble(pdoB);
- if (pdrB.Status == PromptStatus.Cancel)
- {
- return;
- }
- if (pdrB.Status == PromptStatus.None)
- {
- ed.WriteMessage("使用当前凸度:");
- validBulge = true;
- }
- if (pdrB.Status == PromptStatus.OK)
- {
- if (pdrB.Value < -1 || pdrB.Value > 1)
- ed.WriteMessage("\n错误:凸度一般在-1~1之间!");
- else
- {
- _bulgeValue = pdrB.Value;
- validBulge = true;
- }
- }
- }
- break;
- }
- }
- else if (ppr1.Status == PromptStatus.OK)
- {
- p1 = ppr1.Value;
- pointSelected = true; // 退出循环
- }
- else
- {
- // 用户取消或其他状态
- return;
- }
- }
- //获取矩形第二个角触点
- PromptPointOptions ppo = new PromptPointOptions("\n请指第二个点")
- {
- AllowNone = true,
- BasePoint = p1,
- UseBasePoint = true,
- };
- PromptPointResult ppr2 = ed.GetPoint(ppo);
- if (ppr2.Status != PromptStatus.OK)
- return;
- var p3 = ppr2.Value;
- //恢复正交模式
- Acaop.SetSystemVariable("ORTHOMODE", originalOrthoMode);
- //进行坐标点计算并把UCS坐标转为WCS坐标
- double x1 = p1.X;
- double y1 = p1.Y;
- double x2 = p3.X;
- double y2 = p3.Y;
- Point3d p2 = new Point3d(x1, y2, 0);
- Point3d p4 = new Point3d(x2, y1, 0);
- Point3d wcsp1 = UcsToWcs(p1);
- Point3d wcsp2 = UcsToWcs(p2);
- Point3d wcsp3 = UcsToWcs(p3);
- Point3d wcsp4 = UcsToWcs(p4);
- Point2d p2dp1 = new Point2d(wcsp1.X, wcsp1.Y);
- Point2d p2dp2 = new Point2d(wcsp2.X, wcsp2.Y);
- Point2d p2dp3 = new Point2d(wcsp3.X, wcsp3.Y);
- Point2d p2dp4 = new Point2d(wcsp4.X, wcsp4.Y);
- //创建多段线(矩形)
- Polyline pL = new Polyline();
- pL.AddVertexAt(0, p2dp1, 0, 0, 0);
- pL.AddVertexAt(1, p2dp2, 0, 0, 0);
- pL.AddVertexAt(2, p2dp3, 0, 0, 0);
- pL.AddVertexAt(3, p2dp4, 0, 0, 0);
- double pLlenght = pL.Length;
- Polyline revcloud = CreateCloudPolyline(p2dp1, p2dp2, p2dp3, p2dp4, pLlenght); //创建云线
- //日期为命名创建图层,设置颜色及非打印
- string fileName = "ACS-修改" + DateTime.Now.ToString("yyyyMMdd");
- Addlayer(fileName, _colorIndex, false);
- //设置矩形的图层并在模型画出
- revcloud.Layer = fileName;
- revcloud.ColorIndex = _colorIndex;
- AddEntityToModelSpace(revcloud);
- //画引出线,由矩形中心到引出点
- PromptPointResult ppr3 = GetPoint2(ed, "\n请指定引出点位置"); //由ed.GetPoint2("\n请指定引出点位置")改为GetPoint2(ed, "\n请指定引出点位置")
- if (ppr3.Status == PromptStatus.Cancel)
- return;
- if (ppr3.Status == PromptStatus.OK)
- {
- _py = UcsToWcs(ppr3.Value);
- }
- Point3d center = new Point3d((p2dp1.X + p2dp3.X) / 2, (p2dp1.Y + p2dp3.Y) / 2, 0);
- Line line = new Line(center, _py);
- line.Layer = fileName;
- line.ColorIndex = _colorIndex;
- AddEntityToModelSpace(line);
- Matrix3d ucsMatrix = ed.CurrentUserCoordinateSystem;
- double ucsRotation = GetUcsRotationAngle(ucsMatrix);
- if (ppr3.Status == PromptStatus.OK)
- {
- DBText dbText = new DBText
- {
- TextString = "修改说明",
- Position = _py,
- Height = _xxHeight,
- Layer = fileName,
- ColorIndex = _colorIndex,
- Rotation = ucsRotation, // 旋转抵消UCS旋转
- };
- AddEntityToModelSpace(dbText);
- }
- }
- catch (Exception ex)
- {
- ed.WriteMessage($"\n错误: {ex.Message}");
- }
- }
- //创建云线多段线
- private Polyline CreateCloudPolyline(Point2d p1, Point2d p2, Point2d p3, Point2d p4, double lenght)
- {
- Polyline cloud = new Polyline();
- cloud.Closed = true;
- // 云线参数:每边分段数和凸度
- // 四个边:p1->p2, p2->p3, p3->p4, p4->p1
- Point2d[] corners = [p1, p2, p3, p4];
- int vertexIndex = 0;
- for (int side = 0; side < 4; side++)
- {
- Point2d start = corners[side];
- Point2d end = corners[(side + 1) % 4];
- for (int seg = 0; seg <= _segmentValue; seg++)
- {
- double t = (double)seg / _segmentValue;
- double x = start.X + (end.X - start.X) * t;
- double y = start.Y + (end.Y - start.Y) * t;
- // 添加顶点
- cloud.AddVertexAt(vertexIndex, new Point2d(x, y), 0, 0, lenght / 500);
- // 每隔一个点设置凸度,创建云线效果
- if (seg < _segmentValue && seg % 2 == 0)
- {
- cloud.SetBulgeAt(vertexIndex, _bulgeValue);
- }
- else if (seg < _segmentValue)
- {
- cloud.SetBulgeAt(vertexIndex, -_bulgeValue);
- }
- vertexIndex++;
- }
- }
- return cloud;
- }
- public static void Addlayer(string name, int color, bool isTure)
- {
- Database db = HostApplicationServices.WorkingDatabase;
- using Transaction trans = db.TransactionManager.StartTransaction();
- LayerTable lt = (LayerTable)db.LayerTableId.GetObject(OpenMode.ForRead);
- if (!lt.Has(name)) //判断是否已有该图层名字,如有会出错
- {
- lt.UpgradeOpen();
- LayerTableRecord layerTableRecord = new LayerTableRecord()
- {
- Name = name,
- Color = AcadColor.FromColorIndex(ColorMethod.ByAci, (short)color),
- IsFrozen = false, //非冻结
- IsOff = false,
- IsPlottable = isTure,
- };
- lt.Add(layerTableRecord);
- trans.AddNewlyCreatedDBObject(layerTableRecord, true);
- trans.Commit();
- }
- }
- public static void AddEntityToModelSpace(Entity entity)
- {
- Document doc = Acaop.DocumentManager.MdiActiveDocument;
- Database db = doc.Database;
- //开启事务处理
- 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);
- //加直线到块表记录
- btr.AppendEntity(entity);
- //更新数据
- trans.AddNewlyCreatedDBObject(entity, true);
- //事务提交
- trans.Commit();
- }
- // 将点从UCS转换到WCS
- public static Point3d UcsToWcs(Point3d ucsPoint)
- {
- Matrix3d ucsMatrix = Acaop.DocumentManager.MdiActiveDocument.Editor.CurrentUserCoordinateSystem;
- return ucsPoint.TransformBy(ucsMatrix);
- }
- public static PromptPointResult GetPoint2(Editor ed, string promptStr)
- {
- //声明一个获取点的提示类
- PromptPointOptions ppo = new PromptPointOptions(promptStr) { AllowNone = true };
- return ed.GetPoint(ppo);
- }
- private double GetUcsRotationAngle(Matrix3d ucsMatrix)
- {
- // 提取UCS的X轴向量
- Vector3d xAxis = ucsMatrix.CoordinateSystem3d.Xaxis;
- // 计算X轴与WCS X轴(1,0,0)的夹角
- Vector3d wcsXAxis = new Vector3d(1, 0, 0);
- double angle = wcsXAxis.GetAngleTo(xAxis, new Vector3d(0, 0, 1));
- return angle;
- }
- }
另,關於關鍵字直接寫明碼太ugly了,可以看下驚佬寫的這個,里面有關於enum枚舉的寫法來優化關鍵字處理!
https://bbs.mjtd.com/thread-190868-1-1.html网友答:
d1742647821 发表于 2026-2-24 20:01
云线的凸度建议用固定的,不让用户去修改,否则云线就会有超级多的夹点,而不能合并一条线上的夹点
谢谢你的建议,这确实有点鸡肋,后续改进网友答: 大神新年快乐,2026马上发财
网友答:
这个不错,顶起来网友答:
谢谢分享,新年快乐!网友答:
你有种再说一遍 发表于 2026-2-16 18:21
没有用IFox
C#基本都还没搞明白,IFOX太高级了
网友答:
angei83 发表于 2026-2-18 08:57
C#基本都还没搞明白,IFOX太高级了
你能写出来这个已经可以去看IFox的test了网友答: 怎么使用呢?网友答:
wjlove417 发表于 2026-2-19 13:48
怎么使用呢?
加载我附件里面的DLL,使用XX1命令,然后根据提示就可以了