cad.net 脱离cad读取dwg的方法A-TeiGhaForDrawing配置教程
简述
.dwg是Autodesk(桌子)的自己的格式.
.dxf是桌子和其他公司用组码形式交换的格式.
TeiGhaForDrawing (后面都会简称teigha) 是美国开放设计联盟ODA (Open Design Alliance)破解dwg格式的库.所以他们之前打了官司...
然后桌子弹出
"非AutodeskDWG。此DWG文件由非Autodesk开发或许可的软件应用程序保存。将此文件与AutoCAD软件一起使用可能导致稳定性问题。"
桌子会随着新发布的ACAD发布而更新.dwg格式
(就是大家熟知的07版格式,10版格式等等...)以此对抗ODA,
而ODA就紧紧跟在后面并且同步更新...
所以说,现在中望和浩辰都用着ODA的技术来实现dwg的读取,
除非大家不想用dwg格式,否则他们也是无可奈何,
谁叫我们没有中国开放设计联盟.
这里并不提供teigha的下载链接(为了文章永存)
大家自行去对应的网络,QQ群,等等问问其他前辈要就有了
下面是配置teigha的方法,以及c#操作teigha的方法:
Teigha中DWG结构
经常用到的符号表
TextStyleTable/LayerTable/LinetypeTable/BlockTable
及其对应的符号表记录
TextStyleTableRecord/LayerTableRecord/LinetypeTableRecord/BlockTableRecord
及Entity几乎和桌子的一模一样,
不过这个玩意是没有内置的打印函数的,毕竟只是解析.dwg的库.
新建项目
本此展示是一个控制台程序,
当然了,你也可以去用winform/WPF来制作一个具有界面的cad.
新建一个net standard工程.
..csproj上面写入:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>net4.8</TargetFrameworks>
</PropertyGroup>
<PropertyGroup>
<PreBuildEvent>xcopy /y "$(SolutionDir)Teigha_Net_3_09_10(x64)Libs" "$(ProjectDir)bin" /e /s</PreBuildEvent>
</PropertyGroup>
</Project>
版本问题
3.09.10为: x86不可,x64可用
(亲测)
4.00.0为:x86可用
,x64不可(亲测)
非亲测指引:
使用前应该添加TD_Mgd_3.03_9.dll或是其他版本类库,
类库分为64位与32位,
32位类库在64位系统上运行效果可能不太好.
3.02版本及以下版本可能没有64位的类库.
群里来的一张图:
都可以用 net4.0 框架:
然后配置管理器,如果没有就添加x86.
选择x86添加.
注意下面如图设置:
放入引用文件
x86
配置新建里x86,这样才会有 x86 的 Debug 文件夹,
然后将下载的 teigha 4.00.0
压缩包 解压
放入进去x86文件夹,
执行文件.exe 必须在这些 dll中间,也就是输出路径一定也是 bin\x86\Debug\
x64
然后将下载的 teigha 3.09.10
压缩包 解压
放入进去x64文件夹,
执行文件.exe 必须在这些 dll中间,也就是输出路径一定也是 bin\x64\Debug\
想分离的话,我是没有办法的.
可能需要和ODA联系,然后拿到一版源码,然后再设置相对路径,然后再重新编译?
4.00.0添加引用文件:
..\bin\x86\Debug\TD_Mgd_4.00_10.dll
3.09.10添加引用文件:
..\bin\x86\Debug\TD_Mgd.dll
这样就完成了配置文件了.
同类参考
明经通道看到此链接 github.com/FzNoxus/ECAD
代码
这部分的代码和桌子的差不多.
参考的Teigha文件
https://wenku.baidu.com/view/1019d1850b1c59eef9c7b41f.html?tdsourcetag=s_pcqq_aiomsg&qq-pf-to=pcqq.group
参考的错误
https://jingyan.baidu.com/article/bea41d439008dcb4c51be60b.html
命名空间
// 3.02及以下版本命名空间应将Teigha换为DWGdirect
#if Teigha302Dnow
using DWGdirect.DatabaseServices;
using DWGdirect.Geometry;
using DWGdirect.Colors;
using DWGdirect.Export_Import;
using DWGdirect.GraphicsInterface;
using DWGdirect.GraphicsSystem;
using DWGdirect.Runtime;
#else
using Teigha.DatabaseServices;
using Teigha.Geometry;
using Teigha.Colors;
using Teigha.Export_Import;
using Teigha.GraphicsInterface;
using Teigha.GraphicsSystem;
using Teigha.Runtime;
#endif
启动进程服务
namespace JJBoxTeigha;
public class Program {
static void Main(string[] args) {
// 处理数据库之前,需要启用Teigha的服务程序.
// 一个应用程序加上一个就行了,否则出错.
using Services ser = new();
// 打开数据库,不加参数会报错
using Database pDb = new(false, false);
db.ReadDwgFile(Application.StartupPath + "\\TABMENU.dwg",
FileOpenMode.OpenForReadAndWriteNoShare, false, "");
// todo 数据库取得了,再加入你想处理的代码.
// 新建数据库,加参数出错
using Database pDb = new();
// todo 数据库取得了,再加入你想处理的代码.
// 保存数据库
// A.保存格式
// Save12为.DWG(默认不指定为DWG)
// Save13为.DXF
SaveType pSavetype = SaveType.Save12;
// B.保存版本类型
// ACAD2010=vAC24,
// ACAD2007=vAC21,
// ACAD2004=vAC18.
DwgVersion dwgver = DwgVersion.vAC18;
// C.保存语句
pDb.SaveAs(fileName, dwgver);
}
}
之后就是一些代码段的参考了.
2.3 写数据
2.3.1 添加文本样式
public ObjectId CreateTextStyleTableRecord() {
ObjectId styleId = ObjectId.Null;
using var pStyles = (TextStyleTable)pDb.TextStyleTableId.GetObject(OpenMode.ForWrite);
// 创建文本样式记录
using var pStyle = new TextStyleTableRecord();
pStyle.Name = styleName;
pStyle.IsShapeFile = isShapeFile;
// 添加对象到表
styleId = pStyles.Add(pStyle);
// 设置剩下的属性,也可以添加后设置
pStyle.TextSize = textSize;
pStyle.XScale = xScale;
pStyle.PriorSize = priorSize;
pStyle.ObliquingAngle = obliquing;
pStyle.FileName = fileName;
if (isShapeFile)
pStyle.PriorSize = 22.45;
if (!string.IsNullOrEmpty(ttFaceName))
pStyle.Font = new FontDescriptor(ttFaceName, bold, italic, charset, pitchAndFamily);
return styleId;
}
2.3.2 添加线型
using var pLinetypes = (LinetypeTable)pDb.LinetypeTableId.GetObject(OpenMode.ForWrite);
using var pLinetype = new LinetypeTableRecord();
pLinetype.Name = name;
ObjectId linetypeId = pLinetypes.Add(pLinetype); // 添加记录
return linetypeId;
注:线型要有相应的线型文件,且不一定能够加成功,
线型可以在使用之前手动加在dwg模板中,
从其他文件向dwg文件复制线型,可能不成功.
2.3.3 添加块
插入块
// 模型空间
using var btr = (BlockTableRecord)modelSpaceID.GetObject(OpenMode.ForWrite);
// 新建块参照
// 块参照是肉体,块表记录是灵魂
// 肉体多个,灵魂只能有一个
var pBlkRef = new BlockReference(point, btr.ObjectId); // point为插入的位置
pBlkRef.BlockTableRecord = BlockRefID; // 块表记录附着
pBlkRef.ScaleFactors = new Scale3d(scale, scale, scale); // 比例
// 添加到模型空间,就可以显示到模型(布局)了
btr.AppendEntity(pBlkRef);
遍历块表
using var pDb = new Database(false, false);
var file = Application.StartupPath + fileName + ".dwg";
if (!File.Exists(file){
MessageBox.Show("文件不存在" + file);
return ObjectId.Null;
}
// 打开图纸
pDb.ReadDwgFile(file, FileOpenMode.OpenForReadAndAllShare, false, "");
using var bt = (BlockTable)pDb.BlockTableId.Open(OpenMode.ForWrite);
// 遍历块表
foreach (ObjectId id in bt){
using var btr = (BlockTableRecord)id.Open(OpenMode.ForRead);
foreach (ObjectId entid in btr) {
using var pEnt = (Entity)entid.Open(OpenMode.ForRead, false, true);
btr.AppendEntity((Entity)pEnt.Clone());
}
}
2.3.4 向模型空间model,画实体(线,面,圆...)
添加圆
using var c = new Circle();
c.SetDatabaseDefaults(pDb);
btr.AppendEntity(c);
var center = new Point3d(0, 0, 0);
c.Center = center;
c.Radius = 0.5;
添加线
using var blockTable = (BlockTable)pDb.BlockTableId.GetObject(OpenMode.ForWrite);
ObjectId modelSpaceID = blockTable[BlockTableRecord.ModelSpace];
using var btr = (BlockTableRecord)modelSpaceID.GetObject(OpenMode.ForWrite);
using var pline = new Polyline2d();
btr.AppendEntity(pline); // 向块表记录中添加线
// 起点
using var p1 = new Vertex2d();
pline.AppendVertex(p1);
p1.Position = start;
// 终点
using var p2 = new Vertex2d();
pline.AppendVertex(p2);
p2.Position = end;
if (linewidth >= 0.0) {
p2.StartWidth = linewidth;
p2.EndWidth = linewidth;
}
// 闭合,此属性在画线时不加,但在成面时将属性变为true
// pline.Closed = false;
if (linestyle is not null) {
pline.Linetype = linestyle;//线型
}
pline.Layer = LayerName; // 图层名
插入文字
using var btr = (BlockTableRecord)modelSpaceID.GetObject(OpenMode.ForWrite);
using var pText = new DBText();
// 文字插入点同步,这个非常重要
pText.SetDatabaseDefaults(btr.Database);
pText.TextString = text; // 内容
pText.Position = position; // 位置
pText.AlignmentPoint = alignmentPoint; // 对齐点
pText.Height = height; // 高度
pText.WidthFactor = 1.0; // 宽度因子
pText.HorizontalMode = hMode; // 文字模式
pText.VerticalMode = vMode; // 垂直模式
pText.Oblique = OdaToRadian(oblique); // 倾斜
pText.Rotation = OdaToRadian(rotation); // 旋转
pText.Annotative = AnnotativeStates.True; // 注释性
// 文字样式
if (!textstyleID.IsNull)
pText.TextStyleId = textstyleID;
ObjectId textId = btr.AppendEntity(pText);
return textId;
2.3.5 图层
using var pLayers = (LayerTable)pDb.LayerTableId.GetObject(OpenMode.ForWrite);
using var pLayer = new LayerTableRecord();
pLayer.Name = name;
pLayer.Color = Color.FromColorIndex(ColorMethod.ByAci, color);
// 图层线型
using var pLinetypes = (LinetypeTable)pDb.LinetypeTableId.GetObject(OpenMode.ForWrite);
ObjectId linetypeId = pLinetypes[linetype];
pLayer.LinetypeObjectId = linetypeId;
return pLayers.Add(pLayer);
2.4 关于视图
在写完dwg文件之后,打开dwg有时会找不到所画的实体,
因此在保存前应先定义好视图
// 方法一:
using var vt = (ViewportTable)pDb.ViewportTableId.GetObject(OpenMode.ForWrite);
foreach (ObjectId item in vt) {
using var vtr = (ViewportTableRecord)item.GetObject(OpenMode.ForWrite);
vtr.CenterPoint = new Point2d(X, Y);// 定义中心点
vtr.Height = 105;
vtr.Width = 130;
}
// 方法二:
// lm.CurrentLayout 新建时默认为"Model"
LayoutManager lm = LayoutManager.Current;
ObjectId layoutid = lm.GetLayoutId(lm.CurrentLayout);
using var pLayout = (Layout)layoutid.GetObject(OpenMode.ForWrite);
ObjectId viewportid = pLayout.CurrentViewportId;
using var vtr = (ViewportTableRecord)viewportid.GetObject(OpenMode.ForWrite);
vtr.CenterPoint = new Point2d(X, Y); // 定义中心点
vtr.Height = 105;
vtr.Width = 130;
(完)