DXF专题:DXF页面与导入 → 孔位表与工艺 → DXF后处理 → G196扩孔实例
孔位表一章讲清了每个孔怎样保存自己的工艺。本章沿着这些值,依次读懂“生成G代码”、JavaScript后处理、完整程序拼接和“保存载入”。
继续使用四孔图:G81、刀号0、主轴转速1000、R平面2、进给600,停留位置选择“初始平面”。原NO.2(圆心40,10)的孔底Z为−7,其他孔为−5。选择“不排序”,把原NO.2置顶,再按“等于2”筛选,留下三个半径2的孔。程序头和程序尾在本章第3节填写。
现在看 env/dxf/generatecode。第一层循环遍历孔,第二层循环遍历十项工艺,把每个孔的工艺存入 #6001.itemdesc[p]。
这里与导入循环的临时变量用法不同:#6002.channel 表示原始孔号,#6002 主值表示工艺项号。原赋值语句为:
#6001.itemdesc[#6002.channel]=#6001.itemdesc[#6002.channel]+#[6003+#6002].item[#6002.channel]
内层从工艺项0走到9,依次读取 #6003~#6012;每项之间加冒号,最后一项后不加。外层换到下一个原始孔,再从空字符串开始拼接。它会整理所有孔的工艺,后面的内置生成操作再根据勾选决定取哪些孔。
因此,原NO.2置顶后仍读取 #6007.item[1] 得到−7,写入 #6001.itemdesc[1] 的第5个工艺字段:
0:0:1000:0:-7:2:1:2:1:600
依次为:类型、刀号、转速、退刀方式、孔底Z、R平面、G82停留、G83啄孔深度、G83间隙、进给。数值的显示小数位可能不同,字段位置不变。G81不使用中间的G82/G83专用值,但仍保留它们的位置。
随后是生成与显示的关键三句:
#6000.description=widgetFunc["dxfDrill","","",0]
widgetFunc["PlainTextEdit","drillTextEdit","clear",""]
widgetFunc["PlainTextEdit","drillTextEdit","insertText",#6003.description+#6000.description+#6004.description]
第一句把图形和工艺转换成NC正文;第二句清空旧文本;第三句拼接完整程序。
注意同一个参数的不同字段可以承担不同任务:
| 字段 | 用途 |
|---|---|
#6003.item[p] |
孔p的钻孔类型 |
#6003.description |
整个程序的程序头 |
#6004.item[p] |
孔p的刀号 |
#6004.description |
整个程序的程序尾 |
#6000.description |
内置操作返回的生成段 |
看见同一个参数号,不要忽略后面是 .item 还是 .description。
dxfDrill先取得选中孔的圆心和排序结果,再把几何与工艺一起交给运行目录下的:
extScripts/processComplexVerticesMap.js
它是组态能够修改的后处理文件。C++负责读取图形、整理数据和调用它;客户修改输出格式时,通常从这个JS文件入手。
后处理运行时得到两个全局名称:
| 名称 | 内容 |
|---|---|
outputFlag |
本次为字符串 "GCode" |
dataMap |
每个孔的工艺字符串,以及对应的几何点数组 |
用一个孔说明数据形状:
{
"drill0:0:0:1000:0:-7:2:1:2:1:600": [
[ { "x": 40, "y": 10, "z": 0 } ]
]
}
键名开头的 drill0 是生成任务编号,后面才是十项工艺。点数据是两层数组,钻孔点的 x/y 提供孔中心,钻孔深度仍取键名中的工艺Z。
在 processDrillKey 内,key.split(":")切开这些字段,G81分支生成:
vertexStr = "G" + gPrefix + "G81" +
"X" + vertex.x.toFixed(3) + "Y" + vertex.y.toFixed(3) +
"Z" + field5 + "R" + field6 + "F" + field10;
其中 gPrefix=98+退刀方式数值,所以0形成G98,1形成G99。G82分支另加P,并把页面上的停留值乘1000;G83分支另加Q和K。这是本文件的实际生成规则,不能用其他系统的后处理格式替代。
文件后面的总处理部分还负责按刀号排列、换刀和主轴语句:
TnM6 和 G43Hn。M3S...。整个JS执行后的结果字符串返回给 dxfDrill,再回到 #6000.description。这里是生成并返回文字,不是将这些G代码立即交给NC执行。
每次生成都会重新读取这个JS文件并创建新的脚本执行环境。它不依赖上一次调用遗留的JS变量;文件位置按软件工作目录解析,和 env/dxf/ 不是同一个目录。
parts[0] 是 drill0 这样的任务名,不是钻孔类型。十项工艺位于 parts[1]~parts[10]:类型在1、刀号在2、转速在3、停留位置在4、孔底Z在5、R在6、P的输入值在7、Q在8、K在9、进给在10。保持这些位置,原UI和原生成脚本才能继续配合。
原文件先定义 processDrillKey、processNonDrillKey,最后立即执行总处理并返回字符串。它的结束结构是:
return result;
})();
软件取得的是整个文件这次执行的返回值。只添加函数定义、只打印文字、或自行写出一个文件,都不会自动把NC文字放进页面。要改钻孔行格式,通常修改 processDrillKey;要改换刀、主轴和分组结束语句,修改后面的总处理,保留最后的字符串返回。
这是软件内置的Qt JavaScript执行环境。dataMap、outputFlag 由软件提供;普通组态宏变量和 widgetFunc 没有直接作为这两个全局对象的一部分传入。需要新增工艺时,应由组态整理后随工艺字符串传递,不要把 #6007.item[1] 原样写成JS表达式,也不要直接套用Node的 require("fs")。
JS文件打不开或执行报错时,当前调用返回空字符串;已有头尾拼接仍可能留下“只有程序头和程序尾”的文字。因此,看到文本框不为空,还要确认其中确实出现了所选孔的钻孔行。
三个多行编辑框看起来相似,保存方式却不同:
| 对象名 | 原绑定 | 文字怎样被下一步使用 |
|---|---|---|
plainTextEdit,程序头 |
-T(#6003.description) |
离开输入框时写回参数,生成脚本读取该字段 |
plainTextEdit_2,程序尾 |
-T(#6004.description) |
同样写回参数,拼在生成段之后 |
drillTextEdit,程序体 |
没有参数绑定 | 生成脚本直接填入控件;保存载入脚本再读取控件当前文字 |
所以程序头尾改完要让输入框失去焦点,再生成。程序体只是当前编辑器中的文字,不能靠保存默认工艺来保存它;孔位表一章介绍的整页刷新时它也会清空。
在原页面的“程序头”填写以下内容,最后一行后保留换行:
G90G17G40G49G80
G54
G0Z10
在“程序尾”填写,同样保留末尾换行:
G0Z10
M30
这些是本例明确填写的内容,页面不会自动为所有客户选G54或设Z10。数值采用机台当前单位,本例程序未发出G20/G21切换单位。
然后点生成G代码。
点击截图可查看原图。
点击截图可查看原图。
本例完整输出如下,也可下载生成的NC文本:
G90G17G40G49G80
G54
G0Z10
M3S1000 (SPINDLE ON CW)
(--- BEGIN DRILL CYCLE ---)
G98G81X40.000Y10.000Z-7.000R2.000F600.000
(--- BEGIN DRILL CYCLE ---)
G98G81X10.000Y10.000Z-5.000R2.000F600.000
(--- BEGIN DRILL CYCLE ---)
G98G81X10.000Y35.000Z-5.000R2.000F600.000
G80 (CANCEL CANNED CYCLE)
M5 (SPINDLE STOP)
G0Z10
M30
现在可以逐项对应:第一孔为40,10、Z=−7;接着为10,10和10,35、Z=−5;40,35因筛选没有生成;刀号0没有产生换刀语句,但仍然有M3S1000。
左边的连接线表示孔位处理路径,不是G81内部下钻和退刀的完整三维轨迹。需要检查实际循环效果时,应对保存后的NC程序使用软件的程序预览和仿真功能。
拼接操作没有自动补换行。若程序头最后没有换行,最后一条指令可能与生成段开头接在同一行。另一个常见误操作是在“程序体”里手工修改后又点“生成G代码”:原脚本会清空并重建文本,手工修改会被覆盖。
确认程序体内容后点保存载入,输入文件名,例如 dxf-drilling.nc。
loadgcode先读取编辑器当前内容:
#6002.description=widgetFunc["PlainTextEdit","drillTextEdit","plainText",0]
选择路径后,它调用 savefile保存这段文字,再设置程序页面要用的数据。主要关系是:
| 设置 | 后续用途 |
|---|---|
#334.item[1] |
将保存文件加入加工文件列表 |
#9047、#9048.channel、#9048.permission |
告诉代码显示区文件路径、起始显示行和文件行数 |
#403 |
当前加工文件路径 |
#810.permission=0 |
返回程序主页面 |
点击截图可查看原图。
图3 已经载入生成的NC文本;左侧保留的图形来自DXF阶段。载入文件与重新仿真加工程序是不同操作。
保存的是编辑器此刻的内容,因此保存前在程序体内作出的手工修改也会写进文件。原脚本还检查 #929.item[4],当前配置名称为开启逆向加工。值为1时,这条保存载入路径会请求仿真并生成逆向路径;值为0时,只完成保存和载入。本例使用关闭状态。
原脚本在加工或暂停状态下会直接退出保存载入操作。生成后的加工启动、暂停、恢复仍然使用启动、暂停、恢复和停止介绍的原有调度流程。
| 想做的定制 | 先看哪里 | 要保持的对应关系 |
|---|---|---|
| 显示或隐藏DXF入口 | #929.item[12] |
修改宏参数窗口中的子项值 |
| 调整孔参数的名称和选项 | 参数定义、语言包、dxf.ui |
两种语言、输入类型和生成字段一致 |
| 调整以后导入的默认工艺 | #6002、saveDrillParam |
默认值与已经导入的每孔值分开 |
| 改筛选条件或整理顺序 | holeselect、uppath、downpath、headpath |
通过原始孔号访问勾选和工艺 |
| 加固定的程序开头和结束段 | #6003.description、#6004.description |
换行、坐标系、退刀位置及结束码 |
| 改输出格式或工艺语句 | processComplexVerticesMap.js |
十项字段位置、几何点格式、最终返回字符串 |
| 增加一项每孔工艺 | UI、参数定义、导入初始化、保存默认值、生成脚本和JS | 所有环节一起接入,不能只加输入框 |
本例的组态方法可以概括为一条具体的数据路线:
DXF文件 → 内置读图 → 孔位编号和圆心
↓
默认工艺 → 每孔参数 ← 原生表格和输入框
↓
筛选、排列
↓
JS把几何与工艺写成NC文字
↓
程序头 + 生成段 + 程序尾
↓
保存文件 → 标准程序页
内置读图和几何处理提供基础能力,组态决定用户填写什么、怎样组织每孔数据,JS决定输出怎样的程序文字。理解这几个交接位置,就能判断新需求需要修改哪些文件。
回到本例原NO.2的孔底Z=−7,从页面到输出逐步对应:
| 经过的位置 | 具体内容 |
|---|---|
| 点击圆心列 | #9048.version=1,记住原始孔号 |
| 孔底输入框按回车 | lineEdit_4 的绑定把−7写入 #6007.item[1] |
| 将这一孔置顶 | 第一行改为 #6001.itemversion[0]=1,孔深仍在原位置 |
| 生成脚本拼工艺 | 从 #6007.item[1] 取−7,放入 #6001.itemdesc[1] |
| 内置生成整理孔 | 圆心40,10与该孔的工艺一起进入 drill0:... |
| JS生成钻孔行 | parts[5] 成为 field5,写出 Z-7.000 |
| 保存载入 | 从程序体控件读取完整文字并写入选择的NC文件 |
这也给出了定制时的检查顺序:先看输入写到了哪里,再看工艺字符串,最后看JS取的是哪个位置。不要在输出不正确时,同时修改表格、排序和后处理,失去对应关系。
当前原脚本使用 #6002.itemnum 作为工艺项数,又按 6003+项号 查找每孔参数。直接给 #6002 加一个子项,导入和保存循环就会访问下一个参数号;这不是只在默认表末尾多显示一行。 扩展前先确认该参数号在实际工程中没有其他用途,不能根据本章就认定 #6013 可以随意占用。
一次完整扩展应依次处理:定义新项的默认值、输入类型和中英文名称;导入时为每个孔建立相应子项;在正确的工艺区放入按原始孔号绑定的输入;决定“保存参数”是否复制该值;在生成工艺中固定字段位置;最后让JS读取并使用它。若新项不适合继续使用连续参数号,就要同时改导入、保存和生成三处的取值方式。
可以先用本页已有G82练习这条路线:找到停留输入 lineEdit_17,沿 #6009.item[p] 找到工艺的第7项,再找到JS的 parts[7] 和乘1000的处理。这样无需增加新控件,就能理解一个完整工艺项是怎样接入的。
交付时只打包实际修改的UI、组态脚本、语言词条及后处理文件;新增参数要提供只补所需字段的安装步骤。原目录中的 dxf-install 导入整份参数定义文件,可帮助追溯参数来源,不应在已有客户配置上当作普通“刷新”脚本反复执行。包的组织方式见组件部署。
现有 processComplexVerticesMap.js 的 processNonDrillKey 已有轮廓跟随处理:轮廓点的 z在这条数据通道中表示预先计算的切向角,生成代码再以 C=z-90 等处理形成旋转轴角度;实际切深来自另一项工艺参数。
这和钻孔点的z含义不同,也不是本章钻孔十项参数的另一种填法。扩展页面时,需要选择成对的轮廓初始化与生成操作,定义安全高度、切深、进给和延伸量等输入,再把正确的轮廓数据送给已有JS分支。不需要先重写一套法线算法,也不能只打开DXF开关就认为标准钻孔页已经具备轮廓输入。
具体交接位置可以这样对照。右列是后续扩展要接入的设计,当前标准页面仍使用左列:
| 环节 | 标准钻孔 | 法线跟随接入方向 |
|---|---|---|
| 导入后建立清单 | dxfDrillInit |
dxfContourInit |
| 生成入口 | dxfDrill |
dxfContour |
| 工艺文字 | 十项钻孔工艺 | SafeZ:CutZ:Feed:Overcut,分别为安全Z、切削Z、进给、末端延伸或裁短量 |
| JS处理 | processDrillKey |
已有 processNonDrillKey |
| 页面内容 | 圆心、半径筛选、钻孔方式 | 轮廓信息及相应工艺;不能继续按孔半径拆标题 |
| 程序结束 | 本例在程序尾补M30 | 已有轮廓分支会补退刀和M30,重新安排程序尾,避免接在M30之后 |
两类初始化都使用 #6001 保存对象清单。设计模式切换时,应重新建立对应清单,不能拿上一模式的孔编号和工艺去解释轮廓。这是另一条完整的页面接入流程,不能只替换“生成G代码”中的一个函数名。
详细接入关系见已有法线跟随设计。需要AI协助修改后处理时,可参考针对实际数据格式的提示词,同时保留本章已讲清的输入字段和输出规则。
| 现象 | 优先检查 |
|---|---|
| 程序体只有头和尾,缺少钻孔段 | 有无选中孔、钻孔类型是否合法;再检查JS路径和脚本语法 |
| 代码中的孔顺序与列表不同 | 排序策略、刀号分组,以及多位任务编号的字符串次序 |
| 修改程序体后内容又变回去了 | 是否再次点击了“生成G代码” |
| 程序头和第一段接成一行 | 程序头末尾是否保留换行 |
| 点保存载入没有动作 | 当前是否加工中或暂停中;取消文件选择也不会保存 |
掌握这条“页面输入 → 每孔参数 → JS → NC文字”的路线后,下一章在现有页面增加G196扩孔,把一次完整的工艺扩展做出来。