文章目录
- 一、前言
- 二、方法与实践
- 2.1 画出原图,借第三方工具导出至指定格式
- 2.2 CAD导出并转换
- 2.3 两种方法的优劣
- 2.3.1 直接导出代码量大
- 2.3.2 导入导出需要调参
- 三、总结
一、前言
上位机通常有一个设备/场景界面,该界面用于清晰直观地呈现设备状态。
如果界面要求不高,可以用组合简单图形和文字表示设备,并通过给图形变色等手段表示设备状态切换;如果画面要求高,需要做贴图动画甚至是三维模型以更炫酷的方式呈现设备状态。
题外话
有人可能会觉得这种画面做好看了没多大意义,炫酷画面加上动画不会带来实质性的软件提升,还会增加计算机资源消耗。
不过实际情况下,上位机通常是跑在单台主机上的。此时,计算机资源是过剩的,至少不会因为几个动画增加不好的体验。而且,用上位机画面的人和买上位机的人,往往不会关注性能上的东西,谁的上位机感觉更叼一点,画面一比就出结果了。(至少我遇到过几个老板,都是反复强调画面要做炫酷,要有"科技感"一点)。
“将CAD中的图形导出为XAML,以在WPF中使用。”
标题源于一个需求,
一家设备商要做一个上位机系统,功能上不复杂,无非是数据采集、存储、呈现、查询,还有一些业务相关的。但是画面要我尽量做好看些,这对我来说很难。因为这意味着,我不能用几个矩形框加文字的形式来节约工作量了。
此时,我想,该如何把画面做好看?
整体上,我认为的好看就是趋向于逼真,就是没有文字描述的情况下,一眼看过去就知道是哪台设备处于什么状态。
就像外行人评价一幅画画的好不好,通常就是指画的像不像。
二、方法与实践
那如何做的像,有两种思路:
- 自己动手画出大致外观,并对局部图形做变换动画;
- 获取设备图纸,图纸导出为上位机指定格式文件,再导入上位机。
刚开始,我对第二种方法可行性持怀疑态度(我知道可以直接将其导出,但是导出后如何组织以及效果都不确定),
所以果断选择了第一种。
2.1 画出原图,借第三方工具导出至指定格式
第一种方法思路其实很简单,通过矢量图编辑工具(如Inkscape、Adobe Illustrator等),画出大致图形,然后导出成XAML,在WPF中用UserControl将该图形做成控件。
原图形如下,
我在Inkscape中,画了它的大致形状,
很显然,它与实际外观有差,但勉强能用。
接着,在Inkscape中导出成XAML(AI也可以导出,但要装一个插件)。
在WPF中使用XAML,对该图形做中心旋转即可,成品就是下面效果(此时自我感觉良好~):
与二维图一对比,感觉效果还是差很多,更别说是上色后的图了。
对于一些更复杂的图形,就没那么好画了。当然,你也可以放弃细节,硬画。
注意
实际使用时,你可能需要对一个图形的局部做变换。
可以在Inkscape中将要变换的图形合并至一个图层。这样导出的XAML中,会将合并的图形放在一个Canvas中,你可以只对这个Canvas做变换。
2.2 CAD导出并转换
让我放弃第一种方法的,并不是某些图形很难画,而是我简单尝试了第二种方法。
如下,是一张CAD中的网片(DWG/DXF格式),
按照第一种方法,要画出它的大致图形并不难,但也挺繁琐的。
现在,在 Adobe Illustrator(后面简称AI)中打开它,在给AI安装了导出XAML的插件(XAMLExport64.aip)后,在 文件>导出>导出为 中会有该导出选项。
注意
导入AI前后,通常还需要对原图进行编辑,进行内容筛选。(“前”指的是在CAD软件中编辑,“后”指的是AI中编辑)
因为原图可能有边框,有标注,而这些内容在最终界面中是不需要的。
还有画板大小调整,去掉图像周围多余的空白画板区域,可以用AI的 对象>画板>适合图稿边界 调整。
总之,除了会导出这步操作外,你还需要对图形编辑软件有一定掌握。
导出后的文件内容是这样的,很标准的XAML,实际使用时建议将ViewBox中的尺寸去掉,
这是导入WPF的效果,
用Inkscape编辑也和AI类似。
2.3 两种方法的优劣
这样一对比,似乎CAD导出的方式更加好一点?
实际上不一定,这也是我写这篇博客的原因。
CAD导出固然方便,但导出的文件和原图是有偏差的。而这些偏差中,很多是不可控的。
注意
中间经过格式转换,不同软件转换时处理方式不同,会导致结果不同。
比如说原图中的一个圆转换后放大看,可能变成由多段弧组成了。
2.3.1 直接导出代码量大
比如上面那张网片图,你猜AI插件导出的XAML代码有多少行?
在去掉空白行的情况下,有1600+行(再去掉注释行,怎么也得1500行左右)。
这个代码量的图形,你要手动编辑还是比较困难的,只适合一些静态场景。
如果你用自己画的方式去实现,可能生成的代码中只有小几百甚至不到一百行,只需在一个Canvas中放一些线段。
实际项目中,我对一个场景图,使用了CAD直接导出的方式,发现生成的XAML有数十万行代码。这个量级,不要说编辑了,只是复制粘贴到VS编辑器中也得半天时间。在我对原图进行大量不必要元素的滤除后,导出的文件仍然有六万多行代码!
最终导出的XAML中图形元素数量保守估计在两万以上。此时,在AutoCAD中打开原CAD文件是不卡的;在AI中打开就比较卡顿了,严重影响编辑体验;而在Inkscape中直接是卡屏,无法编辑,有时还出现闪退!
所以对于较大的图,不建议直接导出。
你可以对其做一些筛选,或分批部分导出。
具体限制数量没测过,尚未确定,但据我使用体验,我估计当图元的数量>500时,就要考虑分部分导出/或者绘制简化了。
2.3.2 导入导出需要调参
很多时候原图实际尺寸非常大,一个场景图实际可能表示一个房间、一个车间、一个工厂,而CAD绘图时比例往往是1:1。
你用AI打开CAD图时,会出现以下选项:
因为你需要将这么大的图,缩放到一个画板上(AI中画板的最大尺寸是57.8mx57.8m)。
显然一个几百甚至几千平的场地,缩放进一块画布中,有许多要考虑的东西。
这不是我的强项,也不是本文的重点,我这边只能建议你选 缩放以适合画板 ,然后根据显示效果做一些调整。
现在有一幅CAD中看起来好好的图片,按默认选项(缩放以适合画板,不勾选缩放线条粗细)导入AI后是这样的,图形以缩小形态出现在右中上边缘:
将右侧图形区域放大后是这样的,线条变得很粗。
接下来,我们分析一下,为什么会出现这种情况。
首先看原图,下面马赛克区域就是上图的图形部分,
原图外框左下角的点坐标为(1323218.8912,563081.0245),单位是mm。
所以转化成m,是(1323,563),在CAD中缩小全图相对坐标原点位置如下,
下面是导入AI后的,在坐标系中的情况,
- 虽然AI和AutoCAD的默认坐标系不一样,但图形并没有出现颠倒的情况(直觉上来讲,如果坐标系颠倒的话,按原坐标导入的图形也会颠倒)。
- 另外,至于为什么出现横纵坐标比例不一致的情况(原图坐标是(1323,563),AI中是(0.21,0.07)),我想是缩放到画板的过程中做了一些调整(或许和某些不可见图元也有关系)。
- 大概的缩放比例,可以通过图形区域的尺寸比来得到(从下图来看,差不多是缩小6000倍)。宽高比看起来似乎有一点点偏差,可能是由于AI中缩的太小了,尺寸的小数精度的问题。
这步可以看出来,由于不同软件的解析方式不尽相同,图形出现偏差便很难完全把控(即使可以避免,你也得深入学习这些编辑软件,学习成本较高)。
这是与自己绘制相比,一个最大的劣势。
回到上面两个问题的解决方案,
- 第一个问题是图形位置偏移且图形缩太小了。很简单, 前面也提到过,删掉多余的图元后,在工具栏 对象>画板>适合图稿边界 。
- 第二个问题是线条变粗,选择所有对象后,在工具栏 对象>变换>缩放 ,选择合适的倍数即可(实际上,该缩放多少倍才是实际使用中比较纠结的点)。
还有一种方式就是在AI打开CAD文件时,勾选 缩放线条粗细 。这样,整幅图缩小了,连线条也会被缩小,也可以解决线条粗的问题。但是,还是拿上面的图来说,在CAD中,原线条宽度是0.13mm,你跟着缩小6000倍,就变成了2e-5(即0.00002 )mm。你会发现最后导出的XAML显示后,根本看不到图了,因为线条太细了。所以我建议还是自己调整倍数比较好。
这两个问题解决后,至少在AI中,你的图形看起来就很正常了。
在Inkscape中,同样可以做这些操作。但是Inkscape性能方面做的比AI差很多。
在不考虑性能的情况下,我个人还是喜欢用Inkscape,因为它界面友好,导出的XAML也更紧凑。
这小节稍微有点偏题了,本来想说CAD导出这种方式调参太麻烦,结果变成介绍解决问题的方法了。
三、总结
篇幅有点长了,快速总结一下收尾。
- 如果原图形不复杂,建议用编辑工具自己绘制图形,然后转XAML(也可以从iconfont上找现成的图形使用);
- 反之,可以用CAD导出的方式:
- 若CAD较大,筛选图元、裁剪画布后,分几部分导出,建议用AI(需要装脚本);
- 若CAD不大,可以用Inkscape直接导出;
- 必要时,可结合两种方式。