基于ODA的CAD二次开发

无论是基于C++还是C#的CAD二次开发,在编写完插件后,都需要在AutoCAD平台中加载插件才能运行。

但是ODA是一个脱平台的CAD开发库,用户完全可以基于该库编写一个控制台应用程序用来读写DWG文件。

简介

  • ODA:Open Design Alliance

  • 作用:解析、编辑、创建CAD文件,不依赖AutoCAD等软件平台

  • 细节功能:

    • 程序访问DWG/DXF文件
    • 图纸版本转换
    • 创建用于渲染和编辑图纸的应用程序
    • 生成PDF格式的图形缩略图
    • 创建自定义实体
    • C++、C#开发接口
  • 官方文档(需登录查看):https://docs.opendesign.com/td/

ODA技术架构

  • ODA库底层采用C++语言编写,Kernel vc17、Drawings vc17是底层库,后者依赖前者
  • Drawing.NET采用混合编程的方式对底层C++库进行封装,对外提供C#编程接口
  • 在C#项目中,需要引用Drawing.NET库,同时在生成目录下需要带上所有C++依赖库

开发环境

  • 下载SDK,获取激活文件

  • 新建控制台程序

  • 将相关文件拷贝到生成目录下

    • Drawings.NET_vc17_amd64dll_24.9/exe/vc17_amd64dll文件夹下的三个文件

    • Drawings_vc17_amd64dll_24.9\exe\vc17_amd64dll文件夹下的所有.tx和.dll文件
    • Kernel_vc17_amd64dll_24.9\exe\vc17_amd64dll文件夹下的所有.tx和.dll文件
  • 为项目添加引用

  • 引入激活文件

  • 编写源程序

以下程序生成在图纸中创建一个文本:

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
using System;
using Teigha.Core;
using Teigha.TD;

namespace ConsoleApp1
{
class SystemServices : RxSystemServicesImpl
{
public SystemServices()
{
Globals.odActivate(ActivationData.userInfo, ActivationData.userSignature);
}
}

class HostAppServices : ExHostAppServices
{
public override string findFile(string filename, OdRxObject db, FindFileHint hint)
{
string filePath = "";
return filePath;
}
}

internal class Program
{
private static SystemServices sysServices;
private static HostAppServices hostAppServices;

private static void InitODA()
{
sysServices = new SystemServices();
hostAppServices = new HostAppServices();
TD_Db.odInitialize(sysServices);
}

private static void UnInitODA()
{
TD_Db.odUninitialize();
}

static void Main(string[] args)
{
// 初始化ODA
InitODA();
OdDbDatabase db = hostAppServices.createDatabase();
MemoryTransaction transaction = MemoryManager.GetMemoryManager().StartTransaction();

// 添加实体到模型空间
OdDbBlockTableRecord btr = (OdDbBlockTableRecord)db.getModelSpaceId().safeOpenObject(OpenMode.kForWrite);
OdDbText text = OdDbText.createObject();
text.setDatabaseDefaults(btr.database());
text.setPosition(new OdGePoint3d(0, 0, 0));
text.setTextString("testConsole");
btr.appendOdDbEntity(text);

// 添加图层
var layerTable = (OdDbLayerTable)db.getLayerTableId().safeOpenObject(OpenMode.kForWrite);
var layer = OdDbLayerTableRecord.createObject();
layer.setName("测试图层");
layer.setColorIndex(1);
layer.setLineWeight(LineWeight.kLnWtByLayer);
layerTable.add(layer);

MemoryManager.GetMemoryManager().StopTransaction(transaction);
db.writeFile(@"D:\testdwg.dwg", SaveType.kDwg, DwgVersion.kDHL_1032);
db.Dispose();

// 卸载ODA
UnInitODA();
Console.ReadKey();
}
}
}

“九表多词典”操作

获取表和词典的相关方法

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
// 九表
db.getBlockTableId();
db.getModelSpaceId();
db.getPaperSpaceId();
db.getDimStyleTableId();
db.getLayerTableId();
db.getLinetypeTableId();
db.getRegAppTableId();
db.getTextStyleTableId();
db.getUCSTableId();
db.getViewTableId();
db.getViewportTableId();

// 多词典
db.getColorDictionaryId();
db.getDetailViewStyleDictionaryId();
db.getGroupDictionaryId();
db.getLayoutDictionaryId();
db.getMaterialDictionaryId();
db.getMLStyleDictionaryId();
db.getNamedObjectsDictionaryId();
db.getPlotSettingsDictionaryId();
db.getPlotStyleNameDictionaryId();
db.getPointCloudDictionaryId();
db.getScaleListDictionaryId();
db.getSectionViewStyleDictionaryId();
db.getTableStyleDictionaryId();
db.getViewportTableId();

读写模型空间

1
2
3
4
5
6
7
// 添加实体到模型空间
OdDbBlockTableRecord btr = (OdDbBlockTableRecord)db.getModelSpaceId().safeOpenObject(OpenMode.kForWrite);
OdDbText text = OdDbText.createObject();
text.setDatabaseDefaults(btr.database());
text.setPosition(new OdGePoint3d(0, 0, 0));
text.setTextString("testConsole");
btr.appendOdDbEntity(text);

读写块表

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 添加块定义
OdDbBlockTable table = (OdDbBlockTable)db.getBlockTableId().safeOpenObject(OpenMode.kForWrite);
OdDbBlockTableRecord record = OdDbBlockTableRecord.createObject();
OdDbArc arc2 = OdDbArc.createObject();
arc2.setCenter(new OdGePoint3d(0, 0, 0));
arc2.setRadius(50);
arc2.setStartAngle(0);
arc2.setEndAngle(Math.PI * 0.25);
record.appendOdDbEntity(arc2);
OdDbArc arc3 = OdDbArc.createObject();
arc3.setCenter(new OdGePoint3d(0, 0, 0));
arc3.setRadius(150);
arc3.setStartAngle(0);
arc3.setEndAngle(Math.PI * 0.25);
record.appendOdDbEntity(arc3);
record.setOrigin(new OdGePoint3d(0, 0, 0));
record.setName("李浩测试块");
table.add(record);

添加块参照:

1
2
3
4
5
6
// 添加块参照
OdDbBlockReference reference = OdDbBlockReference.createObject();
reference.setBlockTableRecord(table.getAt("李浩测试块"));
reference.setScaleFactors(new OdGeScale3d(1, 2, 1));
reference.setPosition(new OdGePoint3d(500,500,0));
btr.appendOdDbEntity(reference);

读写图层表

1
2
3
4
5
6
7
// 添加图层
var layerTable = (OdDbLayerTable)db.getLayerTableId().safeOpenObject(OpenMode.kForWrite);
var layer = OdDbLayerTableRecord.createObject();
layer.setName("测试图层");
layer.setColorIndex(1);
layer.setLineWeight(LineWeight.kLnWtByLayer);
layerTable.add(layer);

读写分组字典

1
2
3
4
5
6
7
8
9
10
11
// 新建分组
var dict = (OdDbDictionary)db.getMLStyleDictionaryId().safeOpenObject(OpenMode.kForWrite);
if(dict.has("Standard"))
Console.WriteLine("Has Standard MLStyle");
OdDbGroup group = OdDbGroup.createObject();
OdDbObjectIdArray arr = new OdDbObjectIdArray();
var iter = btr.newIterator();
for (iter.start(); !iter.done(); iter.step())
arr.Add(iter.objectId());
group.append(arr);
dict.setAt("测试", group);

评论