详细剖析了CAD的图形交换格式———DXF文件的结构,分析了SVG文件的框架元素和图形元素,建立了CAD中的对象、DXF文件中的实体和SVG中的元素三者之间的对应表,并对转换中遇到的难点问题提出了解决方案,最后,通过编程实现验证了方法的可行性。来源:SVG中国(ChinaSVG.COM) [SVG中国专题文章]
目前CAD技术已广泛应用于建筑设计、机械设计、城市规划、交通等领域,由其主流软件AutoCAD或在之基础上二次开发的软件生成的图纸层出不穷。SVG(Scalable Vector Graphics,可缩放的矢量图形)基于XML标准,既具有开放性,文件较小,显示放缩不损失质量等优点,又有强大的动画交互功能和丰富的滤镜效果。尽管现在已有一些SVG图形的生成工具,但为了充分共享已有的CAD文件,使之能运用于WebGIS或图形发布,因此有必要探讨将CAD文件有效地转换为SVG文件的问题。
AutoCAD的主要图形格式为DWG文件和DXF文件,AutoCAD公司直今未公开DWG文件格式,如要直接读取DWG文件,就需要分析其二进制数据,破译其格式,这种工作相对很困难。另一种方法是利用AutoCAD的二次开发技术,使用如ADS、ObjectARX、VBA、Visual Lisp等开发语言直接访问AutoCAD提供的一组ActiveX接口,获取图形文件中各个图形对象的有用信息,然后使用SVG中相应的元素来描述这些图形对象。但这种方法不能完全脱离AutoCAD平台,应用不够灵活。现在国外对DWG格式的研究也有很多,较为著名的是OpenDWG协会的ODT软件包,该软件包为直接操作DWG文件提供了丰富的函数。但要利用此软件包必须是会员,并且需要缴费,在非盈利条件下可以免费使用。DXF是AutoCAD提供的图形交换格式,它以ASCII码格式存储文件,可以用记事本编辑,简单易读,应用广泛。DXF在表现图形的大小方面十分精确,本文主要探讨了DXF文件转换到SVG文件的一系列问题。
DXF格式是标记AutoCAD图形文件中所包含的全部信息的一种表示方法,最小组成单位是组,每组占两行,第一行是组码,是一个整数,表明了其后数据元素的类型,也指出了数据元素对于给定对象(或记录)类型的含意;第二行是组值,数据类型根据组码的数值可以是字符串型、整型或浮点数型等。一个DXF文件分为七个区域(如图1),每个区域均由多个组组成。每个区域都是以组码0开始,其后跟随着字符串SECTION,接着是组码2和表示区域名称的字符串(例如HEADER),当出现组码0,其后跟随字符串ENDSEC时表示该区域结束。所有区域都结束后,在DXF文件的最后是组码0,后跟组值为字符串EOF作为文件的结束标志。图2是DXF文件中的HEADER区域。一个DXF文件可以只包含七个区域中的若干个区域,而不是全部区域。七个区域中,最重要的是ENTITIES区域。一个最简单的DXF文件可以只包含ENTITIES区域,而不需要包含其他任何区域,这样就大大降低了DXF文件编写的难度。
HEADER区域 |
CLASSES区域 |
TABLES区域 |
BLOCKS区域 |
ENTITIES区域 |
OBJECTS区域 |
THUMBNAIL IMAGE区域 |
表1 DXF文件的组织结构
0 HEADER |
HEADER区域的开始 |
9 $<变量> <组码> <值> |
重复每一头部变量 |
0 ENDSEC |
HEADER区域结束 |
表2 DXF文件中的HEADER区域
DXF文件完整的组织结构说明如下:
SVG矢量图形具有很多优点,与目前网络流行的点阵图
像格式GIF和JPEG相比, SVG能任意对图形显示进行放缩
而保证图像质量,不会出现点阵图常见的锯齿边缘,文件容量相对较小,存储效率高,下载速度快;与矢量动画软件Flash制作的图形相比,也具有一些优势,比如Flash的文件仅能用Flash软件编辑,不利于文档的更改和维护,而SVG图形能用任意的文本编辑工具编辑; Flash的文件与通用的标准技术间缺乏互操作性,如缺乏与HTML 页面或CSS表单互动的机制,而SVG能嵌入到HTML 页面中,支持事件编程,能通过XSL或CSS的方法添加各种样式等。
SVG是XML的扩展,在语法和格式上是XML 规范的一部分,但不属于XML 所能解释的范畴。SVG文档区分大小
写,具有XML的基本属性 :
SVG 1. 0 文档的DOCTYPE声明是:
<?xml version="1.0"?>
<!DOCTYPE svg PUBLIC "-//W3C//DTDSVG1.0//EN"" http://www.w3.org/TR/2001/REC2SVG220010904/DTD/svg10.dtd">
<svg width="800" height="600" xmlns="http://www.w3.org/2000/svg">
</svg>
SVG图形包括框架元素和图形元素。框架元素能够包含图形元素和其他框架元素,如:<svg>、<g>、<defs>、<symbol>、<clipPath>、<mask>、<pattern>、<marker>、<a>和<switch>。<g>元素是编组元素,能分组图形对象,便于管理和使用,如对组进行变换或提供一个公共属性。<defs>元素定义可重用部件,以后可在图形主体中调用,这种重用技术最大限度地利用了HTTP的缓存功能,避免了数据的重复下载。调用<defs>元素定义的项有两种方式,一种是定义的项通过其本地URL(或URI)引用;第二种是使用<use/>元素。
例如: <use xlink:href="#block1"/>
图形元素包含路径<path>、文字<text>、图像<image>、<use>和六种基本形状:矩形<rect>、圆<circle>、椭圆<ellipse>、线<line>、折线<polyline>、多边形<polygon>,简单图形直接由基本形状构建,每个基本形状都带有位置、大小、颜色、轮廓等属性。复杂图形可以用路径<path>来描述,路径是一系列命令,用来创建作为图像一部分精确定义的形状,该形状可以是开放的或闭合的,并可以包含一条或多条线、曲线和线段,其中曲线可用圆弧、三次或两次的Bezier曲线绘制。SVG提供了对嵌入图像的支持,可以在<image>直接写入图像的二进制信息,也可以链接指向某个图像文件,还可以用滤镜中的<feImage>引入外部图像文件加以处理。SVG在字体处理上采用了CSS 2中的字体显示核心技术Web Font,保证在任何情况下看到的字体相同。SVG通过<transform>可以实现坐标转换,实现图形放缩、旋转、镜像、倾斜等效果。
分析DXF文件和SVG文件,发现两者在表示方式上有一定的相似之处,两者均是文本文件,通过记录图形的特征数据来描述矢量图形,比如圆,两者均记录了圆心、半径等数据。但在有些图形的描述上,记录的特征数据是不同的,比如椭圆等。所以,实现CAD文件到SVG文件的转换,不仅要分析AutoCAD中的每一类型的二维矢量图形对象在DXF文件中的对应实体描述,以及SVG中对应于DXF文件中的实体的元素,而且应针对DXF记录的特征数据利用相应的公式推导出SVG需要的数据。经过详细深入的分析,得到AutoCAD中的对象、DXF文件中的实体和SVG中的元素之间的对应如表1所示。
表1 AutoCAD中的对象、DXF文件中的实体和SVG中的元素对应表
AutoCAD中的图形对象 | DXF文件中的实体 | SVG中对应的元素 |
矩形、多边形、多段线 | LWPOLYLINE | polyline |
圆 | CIRCLE | Circle |
椭圆 | ELLIPSE | ellipse、rotate |
直线 | LINE | line |
圆弧 | ARC | path |
椭圆弧 | ELLIPSE | path |
样条曲线 | SPLINE | path |
图块和块引用 | BLOCK、INSERT | defs、g、use等 |
文字 | TEXT、MTEXT | text |
图像 | IMAGE | image |
多线 | MLINE | polyline |
图案填充 | HATCH | defs、g、use等 |
参照线 | XLINE | line |
尺寸 | DIMENSION | defs、g、use等 |
在转换的过程中,会遇到一些难点,下面提出具体的解决方案:
不管是AutoCAD中的对象还是SVG中的图形都是通过坐标定位的。但是两者的坐标系统是不同的, AutoCAD的世界坐标系的原点在屏幕的左下角, X轴的正向朝右, Y轴的正向向上。SVG的坐标系的原点在初始视口(屏幕)的左上角,X轴的正向朝右, Y轴的正向朝下。两者均可以定义自己的坐标系。在DXF文件向SVG文件转换时,为保证图形显示正确,应将所有的图形进行坐标矩阵变换。在SVG中使用下面语句:
<g transform="matrix(1 0 0 21 0 600)">
</g>
由于在DXF文件中的椭圆记录的特征数据和SVG中的椭圆元素需要的数据是不同的, DXF文件记录了椭圆圆心、长轴的端点(相对于圆心的相对值) 、半长轴与半短轴的比例等数据。SVG中的椭圆元素需要椭圆圆心、半长轴、半短轴等数据。并且AutoCAD中的椭圆的长轴可以和水平轴成任意角度,但直接用SVG中的< ellip se >元素所绘的图形只能使椭圆的长轴平行于水平轴,因此,需要计算长轴和水平轴所成角度,再使用旋转变换。所以应利用下面公式转换:
sl = S qr( x23 x2 + y23 y2)
ss = sl3 r1
aa = A tn ( y2 / x2) 3 180 /3. 141 592 6
其中sl代表椭圆的半长轴, ss代表椭圆的半短轴, aa代表椭圆的长轴与水平轴的角度, x2和y2是长轴的端点(相对于圆心的相对值) , r1是半长轴与半短轴的比例。
对所有图形进行了坐标系统转换,但文字不同于其他图形,转换之后会出现了反转,这时应先将文字相对于原所在位置的基线进行镜像,这样能保证文字按正常状态显示。
转换之后,可能出现SVG中的中文不能显示的情况,这是因为SVG有3种编码形式: iso2885921 (ASCII) 、utf28和utf216, iso2885921 (ASCII)不能直接使用汉字字符, utf28和utf216是Unicode形式的编码, utf28支持多语种,每一个ASCII字符使用一个字节来表示,对于其他字符使用三个字节来表示。utf216对于任何一个字符都是使用两个字节来表示,这两种编码能正常显示汉字。在编程时,如果直接写SVG文档,则文档使用的是ASCII码,所以不能正常显示汉字。解决的方案是:
3.3.1 在SVG中,需要将中文字体名称进行“国际化”,即将汉字字体名称改为英文名称,下面是部分字体对照列表(表2) 。
表2 部分汉字字体与英文名称对照表
英文名称 | 汉字字体 | 英文名称 | 汉字字体 |
FangSong_GB2312 | 仿宋_GB2312 | KaiTi_GB2312 | 楷体_GB2312 |
YouYuan | 幼圆 | LiSu | 隶书 |
SimSun | 宋体 | SimHei | 黑体 |
3.3.2 将ASCII码的文档转换成Unicode编码后写文件。下面是VB 实现的代码,将ASCII码的文档读入byte 数组mem,通过StrConv( )转换后,写入文件。
fLength = FileLen (" c: / svg1. svg" )
ReDim mem (fLength) AsByte
Open "c: / svg1. svg" For Binary As #2
Get #2, , mem
Close #2
mem = StrConv(mem, vbUnicode, &H804)
Open svgfilename For Binary As #3
Put #3, , mem
Close #3
对于圆弧、椭圆弧等复杂图形,在SVG中用< Path >元素
描述,其中有椭圆弧命令:
A rx ry x2axis2rotation large2arc2flag sweep2flag x y
其中, rx和ry分别是半长轴和半短轴, x2axis2rotation是弧所在椭圆的X 轴与水平方向的夹角, large2arc2flag 和sweep2flag决定椭圆弧的绘制方向,如果large2arc2flag为1代表大角度弧线,为0代表小角度弧线, sweep2flag为1代表起点到终点的弧线绕椭圆中心是顺时针方向,为0是逆时针方向, x和y是椭圆弧终点坐标。这和DXF中的圆弧、椭圆弧描述的特征数据是不一样的,同样需要转换。
为了提高绘图效率, AutoCAD中提供了图块对象。在DXF中,图块定义在TABLES 区域,在ENTITIES区域通过INSERT组码存储图块调用信息。转换成SVG时,将图块定义用<defs>来组织,图块名作为每个defs元素的ID属性,使用<use>元素调用图块信息。这种方式支持图块的嵌套。
图层是AutoCAD中的一种非常有用的图形管理方式,将图形对象分门别类放在不同的图层中,便于用户管理、编辑和打印。在转换器中,实现了根据图层有选择转换图形,极大地增强了灵活性。
根据上述分析,笔者利用VB编程实现了二维矢量图形从DXF文件到SVG文件的转换,实现算法如下:
- 首先对一个临时SVG文件进行初始化。
- 根据从DXF文件中读出的组码和组值判断对象的类型,不同类型的对象取得不同的属性。
- 进行必要的属性转换,对每个不同对象用SVG中相应的元素来描述。
- 将转换后的结果写到临时的SVG文件中。
- 将临时的SVG文件进行从ASCII码到Unicode编码的转换。
- 将Unicode编码以二进制方式写入目标文件。
本文详细剖析了DXF文件的结构,并且分析了SVG文件的基本要素和框架要素,建立了CAD中的对象、DXF文件中的实体和SVG中的元素三者之间的对应表,并对转换中遇到的坐标系统转换、文字显示、图块、复杂图形的显示等多个问题提出了解决方案,最后,通过VB编程实现验证了方法的可行性。这种转换方法完全不依赖于AutoCAD平台,灵活高效,具有一定的实用价值。