解析DXF文件代码为G代码

By admin at 2017-12-18 • 0人收藏 • 513人看过

为了解析dxf代码,去网上下载了好多知网啊豆丁里面的文档,发现都是个坑.....

这些文档大部分都是只讲了dxf文档结构和解析的好处...然后,一笔带过怎么解析...

晕了...

这玩意解析其实也没那么难,敝帚自珍真的是够了..

怪不得国内开源的少的很,看看国外,唉......


dxf文件是cad的一种格式文本,里面包含了cad图的所有线条和属性, 
G代码是数控里面用到的一种语言,具体百度.

思路很简单,就是读文本一行行处理,然后提取有用信息, 起始关键点是最后那个收尾排序.
因为dxf里面的线条是按照绘制过程中的顺序存储,所以需要排序,连接,这个才能产生G代码的刀路.

因为使用的图形都是一笔画,而且只包含线段和弧线,所以只做了line和arc判断.


由于编辑器字数限制, 以下代码分为两层楼


import win.ui;
/*DSG{{*/
var winform = win.form(text="aardio form";right=759;bottom=469;acceptfiles=1)
winform.add(
button={cls="button";text='\u2460获取有效数据';left=609;top=363;right=757;bottom=466;font=LOGFONT(h=-21);z=2};
button2={cls="button";text='\u2461生成ARC';left=5;top=363;right=138;bottom=466;font=LOGFONT(h=-21);z=3};
button3={cls="button";text='\u2464生成正序G';left=304;top=363;right=436;bottom=466;font=LOGFONT(h=-21);z=6};
button4={cls="button";text='\u2462排序';left=139;top=363;right=221;bottom=466;font=LOGFONT(h=-21);z=4};
button5={cls="button";text='\u2463结果';left=225;top=363;right=300;bottom=466;font=LOGFONT(h=-21);z=5};
button6={cls="button";text="生成反序G";left=442;top=363;right=579;bottom=466;font=LOGFONT(h=-21);z=7};
edit={cls="edit";left=0;top=0;right=760;bottom=362;edge=1;multiline=1;vscroll=1;z=1}
)
/*}}*/

var filePath,fileContents;
import console;
console.open()

winform.wndproc = function(hwnd,message,wParam,lParam){
        select( message ) { 
                //拖拽文件到窗体里
                case 0x233/*_WM_DROPFILES*/{
                        filePath = win.getDropFile(wParam )[1];
                }
                else{
                        
                }
        }
}


class entitiesClass{
        line = {};
        arc = {};
}

class line{
    //线段的第一个点
        float x1 = 0.0;
        float y1 = 0.0;
        float z1 = 0.0;
        //线段的第二个点
        float x2 = 0.0;
        float y2 = 0.0;
        float z2 = 0.0;
};
class arc{
    //弧形的第一个点
        float x1 = 0.0;
        float y1 = 0.0;
        float z1 = 0.0; 
        //弧形第二个点
        float x2 = 0.0;
        float y2 = 0.0;
        float z2 = 0.0;
        //弧形半径
        float R = 0.0;
        //弧形圆心点
        float xx = 0.0;
        float yy = 0.0;
        float zz = 0.0;
        //弧形起始角度和终止角度
        float startN = 0.0;
        float endN = 0.0;
};


var G_line = line();
var G_arc = arc();

var entitiesTab = entitiesClass();
var entitiesStart = false;

winform.button.oncommand = function(id,event){
        winform.edit.text = "";
        fileContents = io.open(filePath,"r+");
        fileContents.seek("set");
        do{
                //读取文件的一行
                var stringLine = tostring(fileContents.read());
                //去除该行的首尾空白字符之后进行判断
                select( string.trim( stringLine ) ) {
                        case "ENTITIES" {
                                console.log("找到实体文件! 开始解析:");
                                entitiesStart = true;
        
                                
                        }
                        case "LINE" {
                                //只有找到实体线条模块之后,线条类型解析才有效
                                if(entitiesStart == true){
                                        //循环读取直到找到线属性这行
                                        while( fileContents.read() != "AcDbLine" ){        };
                                        //LINE线属性共有6组,其中每组第一行是特定属性名,第二行是属性值
                                        for(i=1;6;1){
                                                select( string.trim(tostring( fileContents.read() )) ) {
                                                        case "10" {
                                                                var pos = fileContents.read();
                                                                G_line.x1 = tonumber( string.format("%.3f",pos ) );
                                                        }
                                                        case "20" {
                                                                var pos = fileContents.read();
                                                                G_line.y1 = tonumber( string.format("%.3f",pos ) );
                                                        }
                                                        case "30" {
                                                                var pos = fileContents.read();
                                                                G_line.z1 = tonumber( string.format("%.3f",pos ) );
                                                        }
                                                        case "11" {
                                                                var pos = fileContents.read();
                                                                G_line.x2 = tonumber( string.format("%.3f",pos ) );
                                                        }
                                                        case "21" {
                                                                var pos = fileContents.read();
                                                                G_line.y2 = tonumber( string.format("%.3f",pos ) );
                                                        }
                                                        case "31" {
                                                                var pos = fileContents.read();
                                                                G_line.z2 = tonumber( string.format("%.3f",pos ) );;
                                                        }
                                                        else {
                                                        }
                                                }
                                        
                                        }
                                        //每块LINE类型属性读取完毕,放入LINE表中,等待下一步操作
                                        table.push(entitiesTab.line,table.clone(G_line));
                                }

                        }
                        case "ARC" {
                                        if(entitiesStart == true){
                                                //循环读取直到找到线属性这行
                                                while( fileContents.read() != "AcDbCircle" ){        };
                                                //ARC弧线属性共有6组,其中每组第一行是特定属性名,第二行是属性值
                                                for(i=1;6;1){
                                                        select( string.trim(tostring( fileContents.read() )) ) {
                                                                case "10" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.xx = tonumber( string.format("%.3f",pos ) );
                                                                }
                                                                case "20" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.yy = tonumber( string.format("%.3f",pos ) );
                                                                }
                                                                case "30" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.zz = tonumber( string.format("%.3f",pos ) );
                                                                }
                                                                case "40" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.R = tonumber( string.format("%.3f",pos ) );
                                                                        while( fileContents.read() != "AcDbArc" ){        };
                                                                }
                                                                case "50" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.startN = tonumber( string.format("%.3f",pos ) );
                                                                }
                                                                case "51" {
                                                                        var pos = fileContents.read();
                                                                        G_arc.endN = tonumber( string.format("%.3f",pos ) );
                                                                }
                                                                else {
                                                                }
                                                        }
                                                
                                                }
                                                //每块ARC类型属性读取完毕,放入ARC表中,等待下一步操作
                                                table.push(entitiesTab.arc,table.clone(G_arc));
                                        }
                                }
                        //其他模块暂时不使用,检测到此模块即结束此次解析
                        case "CIRCLE","ELLIPSE","POLYLINE","VERTEX","SPLINE","INDERT","TEXT","DIMENSION" {
                                if(entitiesStart == true){
                                        entitiesStart = false;
                                }
                                
                        }
                        //文件末尾
                        case "EOF" {
                                console.dump(entitiesTab);
                        }
                        else {
                                
                                
                        }
                }

        }while( fileContents.read(0)/**是否是最后一行**/ )

}

//解析获得的ARC数据,求出弧线的起始点坐标和终止点坐标
winform.button2.oncommand = function(id,event){
        for(i=1;#entitiesTab.arc;1){
                if( (entitiesTab.arc[ i ].startN >= 0) && (entitiesTab.arc[ i ].startN <= 90) ){
                        //起始点在第一象限
                        entitiesTab.arc[ i ].x1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.cos(math.rad(entitiesTab.arc[ i ].startN)) + entitiesTab.arc[ i ].xx) );
                        entitiesTab.arc[ i ].y1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.sin(math.rad(entitiesTab.arc[ i ].startN)) + entitiesTab.arc[ i ].yy) );
                        
                }elseif( (entitiesTab.arc[ i ].startN > 90) && (entitiesTab.arc[ i ].startN <= 180) ){
                        //起始点在第二象限
                        entitiesTab.arc[ i ].x1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx - entitiesTab.arc[ i ].R * math.cos(math.rad(180 - entitiesTab.arc[ i ].startN))) );
                        entitiesTab.arc[ i ].y1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.sin(math.rad(180 - entitiesTab.arc[ i ].startN)) + entitiesTab.arc[ i ].yy) );
                        
                }elseif( (entitiesTab.arc[ i ].startN > 180) && (entitiesTab.arc[ i ].startN <= 270) ){
                        //起始点在第三象限
                        entitiesTab.arc[ i ].x1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx - entitiesTab.arc[ i ].R * math.cos(math.rad(entitiesTab.arc[ i ].startN - 180))) );
                        entitiesTab.arc[ i ].y1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].yy - entitiesTab.arc[ i ].R * math.sin(math.rad(entitiesTab.arc[ i ].startN - 180))) );
                        
                }elseif( (entitiesTab.arc[ i ].startN > 270) && (entitiesTab.arc[ i ].startN <=360) ){
                        //起始点在第四象限
                        entitiesTab.arc[ i ].x1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx + entitiesTab.arc[ i ].R * math.cos(math.rad(360 - entitiesTab.arc[ i ].startN))) );
                        entitiesTab.arc[ i ].y1 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].yy - entitiesTab.arc[ i ].R * math.sin(math.rad(360 - entitiesTab.arc[ i ].startN))) );
                        
                }
                
                if( (entitiesTab.arc[ i ].endN >= 0) && (entitiesTab.arc[ i ].endN <= 90) ){
                        //终止点在第一象限
                        entitiesTab.arc[ i ].x2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.cos(math.rad(entitiesTab.arc[ i ].endN)) + entitiesTab.arc[ i ].xx) );
                        entitiesTab.arc[ i ].y2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.sin(math.rad(entitiesTab.arc[ i ].endN)) + entitiesTab.arc[ i ].yy) );
                        
                }elseif( (entitiesTab.arc[ i ].endN > 90) && (entitiesTab.arc[ i ].endN <= 180) ){
                        //终止点在第二象限
                        entitiesTab.arc[ i ].x2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx - entitiesTab.arc[ i ].R * math.cos(math.rad(180 - entitiesTab.arc[ i ].endN))) );
                        entitiesTab.arc[ i ].y2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].R * math.sin(math.rad(180 - entitiesTab.arc[ i ].endN)) + entitiesTab.arc[ i ].yy) );
                        
                }elseif( (entitiesTab.arc[ i ].endN > 180) && (entitiesTab.arc[ i ].endN <= 270) ){
                        //终止点在第三象限
                        entitiesTab.arc[ i ].x2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx - entitiesTab.arc[ i ].R * math.cos(math.rad(entitiesTab.arc[ i ].endN - 180))) );
                        entitiesTab.arc[ i ].y2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].yy - entitiesTab.arc[ i ].R * math.sin(math.rad(entitiesTab.arc[ i ].endN - 180))) );
                        
                }elseif( (entitiesTab.arc[ i ].endN > 270) && (entitiesTab.arc[ i ].endN <=360) ){
                        //终止点在第四象限
                        entitiesTab.arc[ i ].x2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].xx + entitiesTab.arc[ i ].R * math.cos(math.rad(360 - entitiesTab.arc[ i ].endN))) );
                        entitiesTab.arc[ i ].y2 = tonumber( string.format("%.3f", entitiesTab.arc[ i ].yy - entitiesTab.arc[ i ].R * math.sin(math.rad(360 - entitiesTab.arc[ i ].endN))) );
                        
                }

        }
        
}

blob.png

1 个回复 | 最后更新于 2017-12-18
2017-12-18   #1

下半部分:

//定义排序列表
class retClass{
        str G_type;                        //类型
        point G_content;        //内容
}
class lineClass{
        float startX1;
        float startY1;
        float endX1;
        float endY1;
}
class arcClass{
        float R;
        float startX1;
        float startY1;
        float endX1;
        float endY1;
        float centerX;
        float centerY;
}


var retTable = {};
var retType = retClass();
var lineType = lineClass();
var arcType = arcClass();

var 正常顺序 = function( tab , flag ){
        
        if(flag == "line"){
                retType.G_type = "line";
                lineType.startX1 = tab.x1;
                lineType.startY1 = tab.y1;
                lineType.endX1 = tab.x2;
                lineType.endY1 = tab.y2;
                retType.G_content = table.clone( lineType );
                
        }elseif( flag == "arc" ){
                retType.G_type = "逆时针";
                arcType.startX1 = tab.x1;
                arcType.startY1 = tab.y1;
                arcType.endX1 = tab.x2;
                arcType.endY1 = tab.y2;
                arcType.centerX = tab.xx;
                arcType.centerY = tab.yy;
                arcType.R = tab.R;
                retType.G_content = table.clone( arcType );
        }

        return retType; 
        
}
var 颠倒顺序 = function( tab , flag ){
        
        if(flag == "line"){
                retType.G_type = "line";
                lineType.startX1 = tab.x2;
                lineType.startY1 = tab.y2;
                lineType.endX1 = tab.x1;
                lineType.endY1 = tab.y1;
                retType.G_content = table.clone( lineType );
                
        }elseif( flag == "arc" ){
                retType.G_type = "顺时针";
                arcType.startX1 = tab.x2;
                arcType.startY1 = tab.y2;
                arcType.endX1 = tab.x1;
                arcType.endY1 = tab.y1;
                arcType.centerX = tab.xx;
                arcType.centerY = tab.yy;
                arcType.R = tab.R;
                retType.G_content = table.clone( arcType );
        }

        return retType; 
        
}




winform.button4.oncommand = function(id,event){
        
/*
        
取出排好序的表的第一元素的头点坐标,和最后一个元素的尾坐标,

拿其他没有对比过的线条的头坐标和尾坐标分别比较,然后就可以插入到相应的排序表的头和尾部

这样就形成一个连续的队列

难点在对比并放入排序列表的线条,应该放入后从原表中删除,防止多次重复对比,因为每根线条只有唯一的序号,无需再次判断

table貌似没有删除哪一条的指令        
                
*/

        //首先把第一个线条作为第一序列
        //console.dump(entitiesTab.line[1])
        var tempTab = 正常顺序(entitiesTab.line[1],"line");
        table.push(retTable, table.clone(tempTab) );
        table.remove(entitiesTab.line,1);

        while( (#entitiesTab.arc + #entitiesTab.line) ){
                for(k=1;#entitiesTab.arc;1){
                        
                        if((retTable[1].G_content.startX1 == entitiesTab.arc[k].x1) && (retTable[1].G_content.startY1 == entitiesTab.arc[k].y1)){
                                var tempTab = 颠倒顺序(entitiesTab.arc[k],"arc");
                                table.insert(retTable,table.clone(tempTab));//插到前面
                                table.remove(entitiesTab.arc,k);
                                break 1;
                        }
                        
                        if((retTable[1].G_content.startX1 == entitiesTab.arc[k].x2) && (retTable[1].G_content.startY1 == entitiesTab.arc[k].y2)){
                                var tempTab = 正常顺序(entitiesTab.arc[k],"arc");
                                table.insert(retTable,table.clone(tempTab));//插到前面
                                table.remove(entitiesTab.arc,k);
                                break 1;
                        }
                        
                        if((retTable[#retTable].G_content.endX1 == entitiesTab.arc[k].x1) && (retTable[#retTable].G_content.endY1 == entitiesTab.arc[k].y1)){
                                var tempTab = 正常顺序(entitiesTab.arc[k],"arc");
                                table.push(retTable,table.clone(tempTab));//插到后面
                                table.remove(entitiesTab.arc,k);
                                break 1;
                        }
                        
                        if((retTable[#retTable].G_content.endX1 == entitiesTab.arc[k].x2) && (retTable[#retTable].G_content.endY1 == entitiesTab.arc[k].y2)){
                                var tempTab = 颠倒顺序(entitiesTab.arc[k],"arc");
                                table.push(retTable,table.clone(tempTab));//插到后面
                                table.remove(entitiesTab.arc,k);
                                break 1;
                        }

                }
                //-----------------------------------------------------
                for(j=1;#entitiesTab.line;1){
                        //起始点有没重合
                        if((retTable[1].G_content.startX1 == entitiesTab.line[j].x1) && (retTable[1].G_content.startY1 == entitiesTab.line[j].y1)){
                                var tempTab = 颠倒顺序(entitiesTab.line[j],"line");
                                table.insert(retTable,table.clone(tempTab));//插到前面
                                table.remove(entitiesTab.line,j);
                                break 1;
                        }
                        
                        if((retTable[1].G_content.startX1 == entitiesTab.line[j].x2) && (retTable[1].G_content.startY1 == entitiesTab.line[j].y2)){
                                var tempTab = 正常顺序(entitiesTab.line[j],"line");
                                table.insert(retTable,table.clone(tempTab));//插到前面
                                table.remove(entitiesTab.line,j);
                                break 1;
                        }
                        
                        if((retTable[#retTable].G_content.endX1 == entitiesTab.line[j].x1) && (retTable[#retTable].G_content.endY1 == entitiesTab.line[j].y1)){
                                var tempTab = 正常顺序(entitiesTab.line[j],"line");
                                table.push(retTable,table.clone(tempTab));//插到后面
                                table.remove(entitiesTab.line,j);
                                break 1;
                        }
                        
                        if((retTable[#retTable].G_content.endX1 == entitiesTab.line[j].x2) && (retTable[#retTable].G_content.endY1 == entitiesTab.line[j].y2)){
                                var tempTab = 颠倒顺序(entitiesTab.line[j],"line");
                                table.push(retTable,table.clone(tempTab));//插到后面
                                table.remove(entitiesTab.line,j);
                                break 1;
                        }
                        
                }

        }
        console.log("转换完成!");        
}

winform.button5.oncommand = function(id,event){
        
        console.dump(retTable)
        
}

winform.button3.oncommand = function(id,event){
    var GcodeStr;
        for(k,v in retTable){
                
                if(GcodeStr == null){
                        GcodeStr = string.concat(GcodeStr,"G00 ","X",v.G_content.startX1," Y",v.G_content.startY1,'\r\n');
                }
                select(v.G_type) {
                        case "line" {
                                GcodeStr = string.concat(GcodeStr,"G01 ","X",v.G_content.endX1," Y",v.G_content.endY1,'\r\n');
                        }
                        case "顺时针" {
                                GcodeStr = string.concat(GcodeStr,"G02 ","X",v.G_content.endX1," Y",v.G_content.endY1," R",v.G_content.R,'\r\n');
                        }
                        case "逆时针" {
                                GcodeStr = string.concat(GcodeStr,"G03 ","X",v.G_content.endX1," Y",v.G_content.endY1," R",v.G_content.R,'\r\n');
                        }
                        else {
                                console.log("rrrrrrrrrrrrr")
                        }
                }
                
        }
        console.log( GcodeStr );
        string.save("/cnctest.nc",GcodeStr)
}

winform.button6.oncommand = function(id,event){
    var GcodeStr;
    table.reverse(retTable);
        for(k,v in retTable){

                if(GcodeStr == null){
                        GcodeStr = string.concat(GcodeStr,"G00 ","X",v.G_content.endX1," Y",v.G_content.endY1,'\r\n');
                }
                select(v.G_type) {
                        case "line" {
                                GcodeStr = string.concat(GcodeStr,"G01 ","X",v.G_content.startX1," Y",v.G_content.startY1,'\r\n');
                        }
                        case "顺时针" {
                                GcodeStr = string.concat(GcodeStr,"G03 ","X",v.G_content.startX1," Y",v.G_content.startY1," R",v.G_content.R,'\r\n');
                        }
                        case "逆时针" {
                                GcodeStr = string.concat(GcodeStr,"G02 ","X",v.G_content.startX1," Y",v.G_content.startY1," R",v.G_content.R,'\r\n');
                        }
                        else {
                                console.log("rrrrrrrrrrrrr")
                        }
                }
                
        }

        
        console.log( GcodeStr );
        string.save("/cnctestFFFF.nc",GcodeStr)        
}

winform.show() 
win.loopMessage();


登录后方可回帖

登 录
信息栏
本站永久域名:HtmLayout.Cn
纯私人站,当笔记本用的,学到哪写到哪,目前在学aardio+halcon机器视觉.
Htmlayout界面在线学习文档
Sciter中文在线文档Sciter在线学习文档
本 站 主 站:Stm32cube中文网
Aardio 官方站:Aardio官方
Aardio最新功能:Aardio官方更新日志
aardio在线手册Aardio在线手册
C大Aardio论坛:Aar爱好者论坛
简码教程网:简码编程
AARDIO语言QQ群:70517368
赞助商:才仁机械
下载站:非凡软件站
Loading...