OpenCASCADE DataExchange DWG

eryar@163.com

Abstract. DWG is a file format created in the 70’s for the emerging CAD applications. Currently it is the native file format of AutoCAD, a proprietary CAD program developed by Autodesk. Libredwg is a free C library to read and write DWG files. This program is part of GNU project, released under the aegis of GNU. The paper focus on the usage of Libredwg, and use the Libredwg to read a DWG file and output the entities of the DWG to Tcl script for OpenCASCADE Draw Test Harness visualization.

Key Words. OpenCASCADE, DWG, Libredwg, DataExchange, Windows

1. Introduction

DWG是CAD软件AutoCAD及基于AutoCAD的软件保存设计数据所用的一种专有文件格式,始于1970年代的一套Interact CAD软件。之后Autodesk公司于1982年取得版权开始使用这种文件格式。Autodesk公司拥有、开发并且更新DWG文件格式,通常每隔几年DWG就会随着在AutoCAD中添加新的特性而对DWG格式进行更新。

DWG格式及它的ASCII格式变体DXF格式,已经成为CAD制图数据交换中的事实文件标准,据估计全世界有超过十亿个DWG文件。有几家公司正在对DWG文件格式进行逆向工程以试图为其它的设计软件提供读写DWG文件的能力。Autodesk公司也提供了一套需要授权的DWG读写技术开发包“RealDWG”。

新版的AutoCAD可以打开旧版的DWG文件,AutoCAD2007可以打开2.0版本的DWG文件并且可以保存为R14版本。另外Autodesk公司提供一个免费的DWG查看工个“DWG TrueView”用于查看所有版本的DWG文件。另外Autodesk公司是vendor lock-in策略的强力支持者,尽力保护DWG文件格式并且禁止开发支持DWG格式的开放源代码库。

2006年11月12日,Autodesk公司对Open Design Alliance-一款支持DWG格式的自由库OpenDWG提出了诉讼。

ASCII格式的DXF文件的文档Autodesk提供了,但是二进制的DWG格式并没有提供相关文档,由上可见对DWG文件的读写处理是非常困难的。本文主要介绍如何使用Libredwg库来对读取DWG中的几何数据,并将几何数据生成为可以在OpenCASCADE中显示的Tcl脚本,以验证读取数据的正确性。

2.Modify Libredwg for Visual Studio

Libredwg是一个Free的读写DWG文件的C库,这个程序是GNU项目的一部分,授权方式是GNU GPL3。

Libredwg是Libdwg的一个分支,其目的是创建OpenDWG库的一个替代库。也是高优先级的Free软件项目:

http://www.fsf.org/campaigns/priority-projects/priority-projects/highpriorityprojects#ReplaceOpenDWG ,更多信息可访问http://www.gnu.org/software/libredwg 。

从网上下载的Libredwg源程序是在Linux下编译的,并没有配置在Windows下编译方法。为了使用Libredwg可以在Windows上的Visual Studio中编译通过,对Libredwg做了一些修改,最终编译成功。在Visual Studio 2008上成功编译的工程可以文后的链接中下载。

下面给出使用Libredwg读取DWG文件中直线、圆及文字的例子程序:

/*
* load_dwg.c: load a DWG, get lines, text and circles
* written by Felipe Castro
* modified by Felipe Corrêa da Silva Sances
* modified by Thien-Thi Nguyen
*/ #include <dwg.h>
#include "suffix.c" void add_line(double x1, double y1, double x2, double y2)
{
// Make something with that
} void add_circle(double x, double y, double R)
{
// Make something with that
} void add_text(double x, double y, char *txt)
{
// Make something with that
} int load_dwg(char *filename)
{
unsigned int i;
int success;
Dwg_Data dwg; dwg.num_objects = ;
success = dwg_read_file(filename, &dwg);
for (i = ; i < dwg.num_objects; i++)
{
Dwg_Entity_LINE *line;
Dwg_Entity_CIRCLE *circle;
Dwg_Entity_TEXT *text; switch (dwg.object[i].type)
{
case DWG_TYPE_LINE:
line = dwg.object[i].tio.entity->tio.LINE;
add_line(line->start.x, line->end.x, line->start.y, line->end.y);
break;
case DWG_TYPE_CIRCLE:
circle = dwg.object[i].tio.entity->tio.CIRCLE;
add_circle(circle->center.x, circle->center.y, circle->radius);
break;
case DWG_TYPE_TEXT:
text = dwg.object[i].tio.entity->tio.TEXT;
add_text(text->insertion_pt.x, text->insertion_pt.y, text->text_value);
break;
}
}
dwg_free(&dwg);
return success;
} int main (int argc, char *argv[])
{
REQUIRE_INPUT_FILE_ARG (argc);
load_dwg (argv[]);
return ;
}

因为Libredwg用的C编程风格,没有定义导出定义宏,所以决定将Libredwg编译成静态库libredwg.lib,然后使用其头文件及这个静态库的方式来在程序中使用Libredwg库。

经过测试,若DWG中只有简单的线和圆等简单实体,Libredwg还是可以正确读取出。但是若用rewrite的例子来测试写DWG的功能,简单的实例如一个圆的数据都会写出到DWG失败,看样子写的功能还没有完全实现好。

3.DWG to OCC

基于上面的例子程序,结合Libredwg的读取功能,将DWG中的几何数据导出成Tcl脚本,这样就可以方便在OpenCASCADE的Draw Test Harness中来测试结果了。下面给出具体的程序实例及如何在Draw Test Harness中来使用生成的Tcl脚本。

/*
* Copyright (c) 2014 eryar All Rights Reserved.
*
* File : Main.cpp
* Author : eryar@163.com
* Date : 2014-10-15 20:46
* Version : 1.0v
*
* Description : Use libredwg to read data from DWG and
* output them to Tcl script for Draw.
*
* Key words : OpenCASCADE, libredwg, Draw Test Harness
*/ #include "dwg.h" #include <fstream>
#include <iostream> #pragma comment(lib, "../Debug/libredwg.lib") // Output the entities to Tcl for OpenCASCADE Draw.
static std::ofstream theTclExporter("d:/dwg2occ.tcl"); void OutputLine(int id, const Dwg_Entity_LINE* theLine)
{
// Draw Tcl command: vline name xa ya za xb yb zb
theTclExporter << "vline line" << id << " "
<< theLine->start.x << " " << theLine->start.y << " " << theLine->start.z << " "
<< theLine->end.x << " " << theLine->end.y << " " << theLine->end.z << std::endl;
} void OutputCircle(int id, const Dwg_Entity_CIRCLE* theCircle)
{
// Draw Tcl command: circle name x y [z [dx dy dz]] [ux uy [uz]] radius
// 1. make a curve
theTclExporter << "circle circle" << id << " "
<< theCircle->center.x << " " << theCircle->center.y << " " << theCircle->center.z << " "
<< "0 0 1 " << theCircle->radius << std::endl; // 2. make edge from the circle
theTclExporter << "mkedge e" << id << " "
<< "circle" << id << std::endl; // 3. display the circle edge
theTclExporter << "vdisplay e" << id << std::endl;
} void OutputText(int id, const Dwg_Entity_TEXT* theText)
{
// vdrawtext : vdrawtext : vdrawtext name X Y Z R G B hor_align ver_align angle zoomable height Aspect [Font [isMultiByte]]
theTclExporter << "vdrawtext " << theText->text_value << " "
<< theText->insertion_pt.x << " " << theText->insertion_pt.y << ""
<< " 255 255 000 "
<< theText->horiz_alignment << " " << theText->vert_alignment << " "
<< theText->height << " 1 Times-Roman"<< std::endl;
} int LoadDwg(char* theDwgFile)
{
int aResult = ; Dwg_Data aDwgData; aResult = dwg_read_file(theDwgFile, &aDwgData); for (unsigned int i = ; i < aDwgData.num_objects; ++i)
{
switch (aDwgData.object[i].type)
{
case DWG_TYPE_LINE:
OutputLine(i, aDwgData.object[i].tio.entity->tio.LINE);
break; case DWG_TYPE_CIRCLE:
OutputCircle(i, aDwgData.object[i].tio.entity->tio.CIRCLE);
break; case DWG_TYPE_TEXT:
OutputText(i, aDwgData.object[i].tio.entity->tio.TEXT);
break;
}
} return aResult;
} int main(int argc, char* argv[])
{
theTclExporter.flags(std::ios::fixed); theTclExporter << "pload ALL" << std::endl;
theTclExporter << "vinit" << std::endl;
theTclExporter << "vtrihedron tr" << std::endl; if (argc < )
{
std::cout << "please input the dwg file name!" << std::endl;
}
else
{
LoadDwg(argv[]);
} theTclExporter << "vdisplayall" << std::endl;
theTclExporter << "vfit" << std::endl;
theTclExporter << "vhelp" << std::endl; return ;
}

将生成的dwg2occ.tcl在OpenCASCADE的Draw Test Harness中显示如下所示:

Figure 3.1 Import the Tcl script in the Draw Test Hanress of OpenCASCADE

Figure 3.2 Enitites in the DWG file

Figure 3.3 Entities in the Draw Test Harness of OpenCASCADE

通过对比发现,直线和圆已经正确读出,但是文字没有读出来。看来Libredwg的可靠性还有待提高啊。

4.Conclusion

通过使用Libredwg来读取DWG格式中几何数据,并将其转换成OpenCASCADE的Draw Test Harness中能执行的Tcl脚本,以方便测试libredwg读取数据的正确性。

通过简单测试发现,libredwg能读取直线和圆,但是文字内容没有正确读出,看来libredwg的可靠性还有待提高,但是发现这个开源库的更新很缓慢。

5. References

1. DWG Wiki: http://en.wikipedia.org/wiki/.dwg

2. Libredwg: http://www.gnu.org/software/libredwg

3. OpenCASCADE Test Harness User’s Guide 6.7.1

Libredwg for Visual Studio: OpenCASCADE DataExchange DWG

OpenCASCADE DataExchange DWG的更多相关文章

  1. Open Cascade DataExchange DXF

    Open Cascade DataExchange DXF eryar@163.com 摘要Abstract:对DXF文本格式进行详细介绍,并介绍了如何使用开源库dxflib对DXF文件进行读写操作, ...

  2. OpenNURBS to OpenCASCADE

    OpenNURBS to OpenCASCADE eryar@163.com Abstract. The OpenNURBS initiative provides CAD/CAM/CAE and c ...

  3. Qt with OpenCascade

    Qt with OpenCascade 摘要Abstract:详细介绍了如何在Qt中使用OpenCascade. 关键字Key Words:Qt.OpenCascade 一.引言 Introducti ...

  4. Building OpenCascade on Windows with Visual Studio

    Building OpenCascade on Windows with Visual Studio eryar@163.com 摘要Abstract:详细说明OpenCascade的编译配置过程,希 ...

  5. The Installation and Compilation of OpenCASCADE

    OpenCASCADE的编译 The Installation and Compilation of OpenCASCADE eryar@163.com 一. 安装OpenCASCADE 可以从Ope ...

  6. OpenCascade HLR for Pipe Model

    OpenCascade HLR for Pipe Model eryar@163.com 摘要Abstract:在工厂辅助设计(Plant Design)或船舶辅助设计(Ship Design)等CA ...

  7. Open Cascade DataExchange IGES

    Open Cascade DataExchange IGES eryar@163.com 摘要Abstract:本文结合OpenCascade和Initial Graphics Exchange Sp ...

  8. OpenCascade BRep Format Description (2)

    OpenCascade BRep Format Description eryar@163.com 摘要Abstract:本文结合OpenCascade的BRep格式描述文档和源程序,对BRep格式进 ...

  9. OpenCASCADE入门指南

    OpenCASCADE入门指南 eryar@163.com 一.概述 荀子说“君子性非异也,善假于物也”.当你会用英语,就可以与世界各国的人交流:当你会用编程语言,就可以与计算机交流:当你会用数学语言 ...

随机推荐

  1. homebrew update 出现Failure while executing: git pull --quiet origin refs/heads/master:refs/remotes/origin/master解决方案

    具体可以参考https://github.com/Homebrew/homebrew/issues/21002 cd /usr/local git status git reset --hard or ...

  2. tomcat -ROOT 与webapps 的关系,关于部署的一些问题

    现象:之前遇到很奇怪的问题,发完版之后没有效果,页面还是读取上一版的. 反复查找原因发现  http://localhost:8080/mobie 这个路径下的页面是正常的, 而  http://lo ...

  3. JAVA中使用DOM解析XML文件

    XML是一种方便快捷高效的数据保存传输的格式,在JSON广泛使用之前,XML是服务器和客户端之间数据传输的主要方式.因此,需要使用各种方式,解析服务器传送过来的信息,以供使用者查看. JAVA作为一种 ...

  4. 【Telerik】实现列表单元格中添加复选框,进行状态(是、否)判断

    前台界面: 需求:实现对每条细则是否必备进行判断,必备就勾选,否则不勾选. 首先:要保证列表GridView是可编辑的(IsReadOnly=false) 表格代码 其次:单元格的数据绑定要保证是双向 ...

  5. CentOS利用postfix搭建邮件服务器

    之前我用nodemailer通过163邮箱来发送邮件,不过没过几天就一直ETIMEDOUT,不知道什么原因,想着还是自己搭一个来发邮件可能靠谱点(flag?) 安装postfix CentOS 7 自 ...

  6. [Android] 时间Time Date 以及Location中gettime

    import android.text.format.Time; 还有一个是Date Location中的gettime, 这几个每个默认的格式都不一样,直接输出字符串各自得到了不同 比如按照获取当前 ...

  7. linux 进程通信 管道

    1. 管道概述及相关API应用 1.1 管道相关的关键概念 管道是Linux支持的最初Unix IPC形式之一,具有以下特点: 管道是半双工的,数据只能向一个方向流动:需要双方通信时,需要建立起两个管 ...

  8. css简单评论页面

    <!DOCTYPE html> <html> <head> <meta charset='utf-8'> <style> *{margin: ...

  9. Django发送邮件

    1. 配置相关参数 如果用的是 阿里云的企业邮箱,则类似于下面: 在 settings.py 的最后面加上这些 EMAIL_BACKEND='django.core.mail.backends.smt ...

  10. 领域驱动有感<上>

    最近看了<领域驱动设计:软件核心复杂性应对之道>,从字面上来看领域驱动就是解决软件复杂性问题的:然而领域驱动设计的门槛很高,没有很深厚的面向对象编码能力几乎不可能实践成功.Martin F ...