public class Demo{[CommandMethod("xx")]public void Demo1(){using var tr1 = new DBTrans();var doc = Application.DocumentManager.MdiActiveDocument; var db = doc.Database;var ed = doc.Editor;var 圆心 = new Point3d(0, 0, 0); var 半径 = 10.0;using (var tr = db.TransactionManager.StartTransaction()){var bt = tr.GetObject(db.BlockTableId, OpenMode.ForWrite) as BlockTable;var ms = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;var btr = new BlockTableRecord();btr.Name = "MyBlock";if (bt.Has("MyBlock")) {var bid = bt["MyBlock"];bid.EraseBlock();}var bkid = bt.Add(btr); tr.AddNewlyCreatedDBObject(btr, true);Circle cir = new Circle(Point3d.Origin, Vector3d.ZAxis, 1);cir.ColorIndex = 1;var id = btr.AppendEntity(cir); tr.AddNewlyCreatedDBObject(cir, true);Hatch hat = new Hatch();hat.ColorIndex = 1;hat.SetHatchPattern(HatchPatternType.CustomDefined, "SOLID");hat.AppendLoop(HatchLoopTypes.Default, [id]);hat.EvaluateHatch(true); btr.AppendEntity(hat);tr.AddNewlyCreatedDBObject(hat, true);var br = new BlockReference(圆心,bkid);br.ScaleFactors = new Scale3d(半径);ms.AppendEntity(br);tr.AddNewlyCreatedDBObject(br, true);tr.Commit();}}public Polyline 多段线圆(Point3d pt ,double 半径, int colorindex){Polyline pl = new Polyline();var p1 = new Point2d(pt.X - 半径, pt.Y);var p2 = new Point2d(pt.X + 半径, pt.Y);pl.AddVertexAt(0, p1, Math.Tan(Math.PI/4), 0, 0);pl.AddVertexAt(1, p2, Math.Tan(Math.PI / 4), 0, 0);pl.Closed = true;pl.ColorIndex = colorindex;return pl;}}
public static bool EraseBlock(this ObjectId objId){Database db = HostApplicationServices.WorkingDatabase;bool isErase = false;try{using (Transaction trans = db.TransactionManager.StartTransaction()){BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);if (bt.Has(objId)){BlockTableRecord bEra = (BlockTableRecord)objId.GetObject(OpenMode.ForWrite);bEra.Erase();}trans.Commit();isErase = true;}return isErase;}catch (Exception){return isErase;throw;}}
网上
public class Demo
{
[CommandMethod("xx")]
public void Demo1()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// 获取用户输入
var insertPointResult = ed.GetPoint("\n请指定插入点: ");
if (insertPointResult.Status != PromptStatus.OK) return;
Point3d 插入点 = insertPointResult.Value;
var elevationResult = ed.GetDouble("\n请输入高程值: ");
if (elevationResult.Status != PromptStatus.OK) return;
double 高程值 = elevationResult.Value;
double 半径 = 10.0; // 可改为用户输入
using (var tr = db.TransactionManager.StartTransaction()) // 使用单一事务
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForWrite);
var ms = (BlockTableRecord)tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite);
// 块定义处理
string 块名 = "ElevationBlock";
if (bt.Has(块名))
{
// 彻底清除旧块定义及其参照
var oldBtr = (BlockTableRecord)tr.GetObject(bt[块名], OpenMode.ForWrite);
oldBtr.PurgeAll(); // 清除所有关联实体
oldBtr.Erase(true);
}
var btr = new BlockTableRecord { Name = 块名 };
bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
// 创建图形
Circle cir = new Circle(Point3d.Origin, Vector3d.ZAxis, 1);
cir.ColorIndex = 1;
btr.AppendEntity(cir);
tr.AddNewlyCreatedDBObject(cir, true);
// 创建属性定义(动态计算位置)
AttributeDefinition attDef = new AttributeDefinition
{
Position = new Point3d(1.5 * 半径, 0, 0), // 根据半径调整初始位置
Prompt = "高程值",
Tag = "ELEVATION",
TextString = 高程值.ToString("0.00"),
Height = 0.2 * 半径, // 文字高度与半径关联
WidthFactor = 0.8,
Justify = AttachmentPoint.MiddleLeft,
ColorIndex = 1
};
btr.AppendEntity(attDef);
tr.AddNewlyCreatedDBObject(attDef, true);
// 创建块参照
BlockReference br = new BlockReference(插入点, btr.ObjectId);
br.ScaleFactors = new Scale3d(半径); // 缩放因子控制整体尺寸
// 添加属性引用
br.AttributeCollection.AppendAttribute(
new AttributeReference {
TextString = 高程值.ToString("0.00"),
Position = attDef.Position.TransformBy(br.BlockTransform) // 应用变换
});
ms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
tr.Commit();
}
}
// 移除未使用的多段线方法(根据需求决定是否保留)
}
加入jig功能
public class Demo
{
[CommandMethod("xx")]
public void Demo1()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// 第一步:获取高程值
var elevationResult = ed.GetDouble("\n请输入高程值: ");
if (elevationResult.Status != PromptStatus.OK) return;
double 高程值 = elevationResult.Value;
// 第二步:创建块定义
string 块名 = "ElevationBlock";
ObjectId blockId;
using (var tr = db.TransactionManager.StartTransaction())
{
var bt = (BlockTable)tr.GetObject(db.BlockTableId, OpenMode.ForRead);
// 如果块不存在则创建
if (!bt.Has(块名))
{
bt.UpgradeOpen();
var btr = new BlockTableRecord { Name = 块名 };
// 创建圆形(基准尺寸为1单位)
var cir = new Circle(Point3d.Origin, Vector3d.ZAxis, 1);
cir.ColorIndex = 1;
btr.AppendEntity(cir);
tr.AddNewlyCreatedDBObject(cir, true);
// 创建属性定义
var attDef = new AttributeDefinition
{
Position = new Point3d(1.5, 0, 0), // 相对位置
Tag = "ELEV",
Prompt = "高程值",
TextString = "0.00",
Height = 0.2, // 基准文字高度
ColorIndex = 1,
Justify = AttachmentPoint.MiddleLeft
};
btr.AppendEntity(attDef);
tr.AddNewlyCreatedDBObject(attDef, true);
blockId = bt.Add(btr);
tr.AddNewlyCreatedDBObject(btr, true);
}
else
{
blockId = bt[块名];
}
tr.Commit();
}
// 第三步:使用Jig交互式插入
using (var tr = db.TransactionManager.StartTransaction())
{
var ms = (BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(db),
OpenMode.ForWrite);
// 创建临时块参照
var br = new BlockReference(Point3d.Origin, blockId)
{
ScaleFactors = new Scale3d(10) // 默认缩放因子
};
// 设置属性值
var attCol = br.AttributeCollection;
foreach (ObjectId attDefId in br.BlockTableRecord.GetObject<BlockTableRecord>())
{
if (attDefId.ObjectClass.DxfName == "ATTDEF")
{
var attDef = tr.GetObject(attDefId, OpenMode.ForRead) as AttributeDefinition;
var attRef = new AttributeReference();
attRef.SetAttributeFromBlock(attDef, br.BlockTransform);
attRef.TextString = 高程值.ToString("0.00");
attCol.AppendAttribute(attRef);
tr.AddNewlyCreatedDBObject(attRef, true);
}
}
// 启动拖动Jig
var jig = new BlockJig(br, 高程值);
var result = ed.Drag(jig);
if (result.Status == PromptStatus.OK)
{
ms.AppendEntity(br);
tr.AddNewlyCreatedDBObject(br, true);
tr.Commit();
}
else
{
tr.Abort();
}
}
}
// Jig实现类
public class BlockJig : EntityJig
{
private double _elevation;
private Point3d _insertPoint;
public BlockJig(BlockReference br, double elevation) : base(br)
{
_elevation = elevation;
_insertPoint = br.Position;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
var opts = new JigPromptPointOptions("\n指定插入点: ");
opts.UserInputControls = UserInputControls.NullResponseAccepted;
var res = prompts.AcquirePoint(opts);
if (res.Status == PromptStatus.OK)
{
if (_insertPoint.DistanceTo(res.Value) < Tolerance.Global.EqualPoint)
return SamplerStatus.NoChange;
_insertPoint = res.Value;
return SamplerStatus.OK;
}
return SamplerStatus.Cancel;
}
protected override bool Update()
{
((BlockReference)Entity).Position = _insertPoint;
// 更新属性位置
var tr = Entity.Database.TransactionManager.TopTransaction;
foreach (ObjectId attId in ((BlockReference)Entity).AttributeCollection)
{
var attRef = tr.GetObject(attId, OpenMode.ForWrite) as AttributeReference;
attRef.Position = attRef.Position.TransformBy(
Matrix3d.Displacement(_insertPoint - Point3d.Origin));
}
return true;
}
}
}
封装jig
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using System.Collections.Generic;
public static class EntityJigger
{
/// <summary>
/// 交互式拖动插入多个实体
/// </summary>
/// <param name="entities">要插入的实体列表(建议使用未添加到数据库的副本)</param>
/// <param name="basePoint">实体组合的基准点</param>
/// <returns>最终的插入点(如果取消返回null)</returns>
public static Point3d? DragEntities(List<Entity> entities, Point3d basePoint)
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
using (var tr = db.TransactionManager.StartTransaction())
{
try
{
// 创建临时实体副本
var tempEntities = new List<Entity>();
foreach (var ent in entities)
{
var clone = ent.Clone() as Entity;
clone.TransformBy(Matrix3d.Displacement(basePoint.GetVectorTo(Point3d.Origin)));
tempEntities.Add(clone);
}
// 创建Jig实例
var jig = new MultiEntityJig(tempEntities, basePoint);
var result = ed.Drag(jig);
if (result.Status == PromptStatus.OK)
{
// 正式添加实体到模型空间
var ms = (BlockTableRecord)tr.GetObject(
SymbolUtilityServices.GetBlockModelSpaceId(db),
OpenMode.ForWrite);
foreach (var ent in tempEntities)
{
ms.AppendEntity(ent);
tr.AddNewlyCreatedDBObject(ent, true);
}
tr.Commit();
return jig.InsertPoint;
}
tr.Abort();
return null;
}
catch
{
tr.Abort();
throw;
}
}
}
/// <summary>
/// 多实体拖动Jig实现
/// </summary>
private class MultiEntityJig : DrawJig
{
private readonly List<Entity> _entities;
private Point3d _basePoint;
private Point3d _insertPoint;
public Point3d InsertPoint => _insertPoint;
public MultiEntityJig(List<Entity> entities, Point3d basePoint)
{
_entities = entities;
_basePoint = basePoint;
_insertPoint = basePoint;
}
protected override SamplerStatus Sampler(JigPrompts prompts)
{
var opts = new JigPromptPointOptions("\n指定插入点: ")
{
UserInputControls = UserInputControls.Accept3dCoordinates |
UserInputControls.NoZeroResponse |
UserInputControls.NoNegativeResponse
};
var result = prompts.AcquirePoint(opts);
if (result.Value.DistanceTo(_insertPoint) < Tolerance.Global.EqualPoint)
return SamplerStatus.NoChange;
_insertPoint = result.Value;
return SamplerStatus.OK;
}
protected override bool WorldDraw(WorldDraw draw)
{
// 计算位移矩阵
var vector = _basePoint.GetVectorTo(_insertPoint);
var matrix = Matrix3d.Displacement(vector);
// 绘制所有临时实体
foreach (var ent in _entities)
{
draw.Geometry.Draw(ent);
ent.TransformBy(matrix);
}
return true;
}
}
}
[CommandMethod("testJig")]
public void TestJigCommand()
{
var doc = Application.DocumentManager.MdiActiveDocument;
var db = doc.Database;
var ed = doc.Editor;
// 创建要插入的实体集合
var entities = new List<Entity>();
// 创建圆形(基准位置在原点)
var circle = new Circle(Point3d.Origin, Vector3d.ZAxis, 5);
circle.ColorIndex = 1;
entities.Add(circle);
// 创建单行文字
var text = new DBText
{
Position = new Point3d(8, 0, 0),
TextString = "高程值",
Height = 2,
ColorIndex = 2,
Justify = AttachmentPoint.MiddleLeft
};
entities.Add(text);
// 设置基准点(通常取组合的中心点)
var basePoint = new Point3d(0, 0, 0);
// 调用Jig进行拖动插入
var resultPoint = EntityJigger.DragEntities(entities, basePoint);
if (resultPoint.HasValue)
{
ed.WriteMessage($"\n插入点坐标:{resultPoint.Value}");
}
}