前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >图形编辑器基于Paper.js教程18:图片编辑器支持导入dxf文件,dxf文件解析,dxf文件转gcode

图形编辑器基于Paper.js教程18:图片编辑器支持导入dxf文件,dxf文件解析,dxf文件转gcode

作者头像
拿我格子衫来
发布2024-12-28 10:29:33
发布2024-12-28 10:29:33
8900
代码可运行
举报
文章被收录于专栏:TopFETopFE
运行总次数:0
代码可运行

前几个月在图像编辑器中完成了导入dxf的功能,趁现在有点时间来总结一下这一功能的实现思路和难点。

dxf文件的内容如下:

后缀名为dxf

dxf的文件内容是文本,很类似json,yaml 结构,里面定义了通过一个一个的属性和属性值。

有图层,圆,线,多线段,嵌套对象,弧度,字体。 更多的对象可以查看官方文档

这个pdf可以查看到 https://images.autodesk.com/adsk/files/autocad_2012_pdf_dxf-reference_enu.pdf

中文版 在线 https://help.autodesk.com/view/ACD/2024/CHS/?guid=GUID-FCEF5726-53AE-4C43-B4EA-C84EB8686A66

解析dxf 使用是这个前端库 https://github.com/gdsestimating/dxf-parser

另外还有个使用threejs来预览dxf文件的库。https://github.com/gdsestimating/three-dxf 使用它可以帮助我们画出的dxf图形是否准确。

输出内容示例

代码语言:javascript
代码运行次数:0
复制
{
   "header": {
      "$ACADVER": "AC1027",
      "$ACADMAINTVER": 55,
      "$DWGCODEPAGE": "ANSI_1252",
      "$REQUIREDVERSIONS": 0,
      "$INSBASE": {
         "x": 0,
         "y": 0,
         "z": 0
      },
      "$EXTMIN": {
         "x": 146.8403717847312,
         "y": 141.8294137695975,
         "z": -5.934454319554902
      },
      "$EXTMAX": {
         "x": 762.6679804989191,
         "y": 545.821967323924,
         "z": 6.065545680445099
      }
   },
   "tables": {
      "lineType": {
         "handle": "5",
         "ownerHandle": "0",
         "lineTypes": {
            "Continuous": {
               "name": "Continuous",
               "description": "Solid line",
               "patternLength": 0
            },
            "HIDDEN2": {
               "name": "HIDDEN2",
               "description": "Hidden (.5x) _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _",
               "pattern": [
                  0.125,
                  -0.0625
               ],
               "patternLength": 0.1875
            },
            "CENTER": {
               "name": "CENTER",
               "description": "____ _ ____ _ ____ _ ____ _ ____ _ ____ _ ____",
               "pattern": [
                  1.25,
                  -0.25,
                  0.25,
                  -0.25
               ],
               "patternLength": 2
            }
         }
      },
      "layer": {
         "handle": "2",
         "ownerHandle": "0",
         "layers": {
            "FG-Dim": {
               "name": "FG-Dim",
               "visible": true,
               "color": 16711680
            },
            "FG-Dtl-Hatch": {
               "name": "FG-Dtl-Hatch",
               "visible": true,
               "color": 8421504
            },
            "FG-Dtl-Hidden": {
               "name": "FG-Dtl-Hidden",
               "visible": false,
               "color": 16711680
            },
            "Vport": {
               "name": "Vport",
               "visible": false,
               "color": 65535
            },
            "FG-Logo": {
               "name": "FG-Logo",
               "visible": true,
               "color": 16711680
            }
         }
      }
   },
   "blocks": {
      "*U34": {
         "handle": "2269",
         "ownerHandle": "2268",
         "layer": "0",
         "name": "*U34",
         "type": 3,
         "position": {
            "x": 0,
            "y": 0,
            "z": 0
         },
         "name2": "*U34",
         "xrefPath": "",
         "entities": [
            {
               "type": "LINE",
               "vertices": [
                  {
                     "x": 0.1875,
                     "y": 0,
                     "z": 0
                  },
                  {
                     "x": -0.1875,
                     "y": 0,
                     "z": 0
                  }
               ],
               "handle": "226C",
               "ownerHandle": "2268",
               "layer": "0"
            },
            {
               "type": "LINE",
               "vertices": [
                  {
                     "x": 0,
                     "y": 0.1875,
                     "z": 0
                  },
                  {
                     "x": 0,
                     "y": 0.6811772682290212,
                     "z": 0
                  }
               ],
               "handle": "226F",
               "ownerHandle": "2268",
               "layer": "0"
            }
         ]
      }
   },
   "entities": [
      {
         "type": "LINE",
         "vertices": [
            {
               "x": 516.4647237971784,
               "y": 330.7069626367825,
               "z": 0
            },
            {
               "x": 516.1834738922776,
               "y": 330.8693422367825,
               "z": 0
            }
         ],
         "handle": "1805",
         "ownerHandle": "1F",
         "layer": "FG-Dtl-Fastener"
      },
      {
         "type": "LWPOLYLINE",
         "vertices": [
            {
               "x": 520.4823233451135,
               "y": 335.7037165715653,
               "bulge": 0.495500738389451
            },
            {
               "x": 520.4823233451135,
               "y": 335.385455702,
               "bulge": -0.7180232138070655
            },
            {
               "x": 520.4641507323038,
               "y": 335.3315861367825
            },
            {
               "x": 520.09745368689,
               "y": 335.3315861367825,
               "bulge": 0.2818610536572053
            },
            {
               "x": 519.9994740971791,
               "y": 335.3915861367824
            },
            {
               "x": 519.9334740971784,
               "y": 335.3915861367824
            },
            {
               "x": 519.9334740971784,
               "y": 335.6975861367825
            },
            {
               "x": 519.9994740971791,
               "y": 335.6975861367825,
               "bulge": 0.2818610536572062
            },
            {
               "x": 520.09745368689,
               "y": 335.7575861367824
            },
            {
               "x": 520.4641507323034,
               "y": 335.7575861367824,
               "bulge": -0.7180232138063462
            }
         ],
         "handle": "13E1",
         "ownerHandle": "1F",
         "layer": "SHAPE",
         "shape": true
      },
      {
         "type": "CIRCLE",
         "handle": "17EA",
         "ownerHandle": "1F",
         "layer": "FG-Dtl-Fastener",
         "center": {
            "x": 516.1834740971784,
            "y": 329.0445861367825,
            "z": 0
         },
         "radius": 0.1875
      },
      {
         "type": "ARC",
         "handle": "17F6",
         "ownerHandle": "1F",
         "layer": "FG-Dtl-Fastener",
         "center": {
            "x": 516.1834740971784,
            "y": 330.4508361367829,
            "z": 0
         },
         "radius": 0.28125,
         "startAngle": 0,
         "angleLength": 3.141592653589793,
         "endAngle": 3.141592653589793
      },
   ]
}

我们主要是用的是 entities 这个数组内的数据, 每一个元素都应该被当作一个独立的元素,导入到画布中也是单独的元素,可以独立操作。 dxf中也有图层的概念。

最终导入的dxf

带有图层的 dxf解析使用不同的颜色,来表示不同的图层。有些图层是要雕刻,有些图层是要切割。加工更加方便。

在解析dxf时,由于dxf的坐标原点是在左下角,而一般的画布 canvas的原点是在左上角,这里就需要做一个反转。要做反转就需要计算dxf整体的边框尺寸,使用边框尺寸进行反转。这部分在解析字体时非常麻烦,我看有些激光雕刻机软件直接就没有解析字体。另外还有弧度,嵌套元素,都是比较麻烦的。 在渲染dxf的内容时 需要先计算出整体的边框,然后在计算每个元素坐标时,使用边框和元素的原始数据进行反转。最终实现坐标系的转换。这是比较普通的一种做法,还有一种做法是,先按照dxf的原始数据渲染元素,然后获取dxf所有元素的边框, 最后将dxf的所有元素 反转一遍。利用图形化canvas库的能力进行反转,而不是逐个地将原始坐标反转。

看一下调试的数据

针对每个dxf的实体都需要写一个独立的解析方法。

代码语言:javascript
代码运行次数:0
复制
    switch (entity.type) {
      case "LINE":
        addItem = drawLine(entity, offsetX, offsetY);
        break;
      case "CIRCLE":
        addItem = drawCircle(entity, offsetX, offsetY);
        break;
      case "ARC":
        addItem = drawArc(entity, offsetX, offsetY);
        break;
      case "POLYLINE":
      case "LWPOLYLINE":
        addItem = drawPolyline(entity, offsetX, offsetY);
        break;
      case "SPLINE":
        addItem = drawSpline(entity, offsetX, offsetY);
        break;
      case "INSERT":
        drawInsert(entity, block, offsetX, offsetY, selectLayerConfig);
        break;
      case "MTEXT":
        addItem = (await drawMText(entity, offsetX, offsetY)) as paper.Item; //1234 假设提供了一些偏移值
        setLaserData(addItem, selectLayerConfig.color);
        break;
    }

做这个dxf解析 我一个人也做了两个星期。不少细节都是边查资料边做。

最后再补充一下,市面上还有一个库 叫dxf, https://www.npmjs.com/package/dxf 可以直接将dxf的内容转换成svg,然后画布再导入svg,整个流程非常简单,就导入dxf的问题,转换成了导入svg的问题。 但是这个有一个缺点,就是无法直接获取图层信息。 我不清楚dxf转svg时,能不能携带图层的信息,但svg本身是没有图层这个概念的,而dxf有。

这两天有人使用toocaastudio时,发现矩形的圆角 没办法显示出来。看来后面还需要再优化一下。😑心累

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2024-12-26,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档