C#基于Autocad的二次开发(4.块的移动)

开始之前确保已完成步骤1创建解决方案和类库项目,并在对应项目中安装nuget包

一般情况下,如果需要移动快,只需要改变块的插入坐标值,那么块的插入位置自然而然的就会发生变化,但是在某些特殊场景,我们需要基于块原来的位置,通过偏移的坐标量来移动块,这时需要额外的特殊处理,因此我们需要先找到目标块,接着修改目标块的坐标位置为新的坐标。

在步骤2.块的插入中,”插入块类”InsertBlockParam的基础之上添加字段BlockId,用于块的唯一标识,由业务赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
/// <summary>
/// 插入块类
/// </summary>
public class InsertBlockParam
{
/// <summary>
/// 图层名称
/// </summary>
public string LayerName { get; set; }
/// <summary>
/// 块名称
/// </summary>
public string BlockName { get; set; }
/// <summary>
/// 块物理路径
/// </summary>
public string BlockPath { get; set; }
/// <summary>
/// 块插入坐标
/// </summary>
public ACDPoint3D InsertPoint { get; set; }

public Guid BlockId { get; set; }

public InsertBlockParam() { }

public InsertBlockParam(string layerName, string blockName, string blockPath, ACDPoint3D insertPoint, Guid blockId)
{
LayerName = layerName;
BlockName = blockName;
BlockPath = blockPath;
InsertPoint = insertPoint;
BlockId = blockId;
}
}

“点位类”ACDPoint3D实现IEquatable,重写Equals方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
/// <summary>
/// 点位类
/// </summary>
public class ACDPoint3D:IEquatable<ACDPoint3D>
{
public double X { get; set; }
public double Y { get; set; }
public double Z { get; set; }

public ACDPoint3D() { }

public ACDPoint3D(double x, double y, double z)
{
X = x;
Y = y;
Z = z;
}

public bool Equals(ACDPoint3D other)
=> X == other.X && Y == other.Y && Z == other.Z;
}

ACD.CadCore项目中创建类文件ACDOperation.MoveBlock.cs,实现块的移动操作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
public partial class ACDOperation
{
public bool MoveBlock(string dwgFilePath, string newFilePath, IEnumerable<InsertBlockParam> blockOldPositions, IEnumerable<InsertBlockParam> blockNewPositions)
{
bool result = true;

CheckFilePath(dwgFilePath, newFilePath);

File.Copy(dwgFilePath, newFilePath, true);

using (Database blockDb = new Database(false, true))
{
blockDb.ReadDwgFile(newFilePath, FileOpenMode.OpenForReadAndWriteNoShare, true, null);
blockDb.CloseInput(true);

result = MoveBlock(blockDb, blockOldPositions, blockNewPositions);
}

if (!result) File.Delete(newFilePath);

return result;
}

public bool MoveBlock(IDynamicMetaObjectProvider database, IEnumerable<InsertBlockParam> blockOldPositions, IEnumerable<InsertBlockParam> blockNewPositions)
{
bool result = true;

ACDPoint3D blockRefPoint;
BlockTable currblockTable;
BlockReference blockReference;
BlockTableRecord currblockTableRecord;

Database currdb = database as Database;

using (Transaction currentTrans = currdb.TransactionManager.StartTransaction())
{
try
{
currblockTable = currentTrans.GetObject(currdb.BlockTableId, OpenMode.ForRead) as BlockTable;

currblockTableRecord = currentTrans.GetObject(currblockTable[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;

InsertBlockParam oldBlockPostion, newBlockPosition;
foreach (var record in currblockTableRecord)
{
var entity = currentTrans.GetObject(record, OpenMode.ForWrite);
if (entity is BlockReference)
{
blockReference = entity as BlockReference;
blockRefPoint = new ACDPoint3D(blockReference.Position.X, blockReference.Position.Y, blockReference.Position.Z);

oldBlockPostion = blockOldPositions.FirstOrDefault(x =>x.InsertPoint.Equals(blockRefPoint));

if (oldBlockPostion != null)
{
newBlockPosition = blockNewPositions.FirstOrDefault(x => x.BlockId == oldBlockPostion.BlockId);
if (newBlockPosition != null)
{
blockReference.Position = new Point3d(newBlockPosition.InsertPoint.X, newBlockPosition.InsertPoint.Y, newBlockPosition.InsertPoint.Z);
}
}
}
}
currentTrans.Commit();
}
catch (Exception)
{
currentTrans.Abort();
result = false;
}
}
return result;
}
}

blockOldPositions来自上一次插入块时的执行参数,通过上一次插入块时的坐标位置找到目标块,再通过目标块的BlockId,在blockNewPositions中找到目标块对应的新的参数,将目标块的Position重新赋值,最后提交事物。


C#基于Autocad的二次开发(4.块的移动)
https://wangyuangen.github.io/2024/05/20/CsharpAutocad4/
作者
Yuangen Wang
发布于
2024年5月20日
许可协议