【Linux+Qt】CAM-基于dxf文件的铣削路径生成源码学习

f33c609601dcbece5bab21a92bbb0e34.png生成Contours:外加工轮廓

f3fb8a224aff1b93b3448baa38cdb2b8.png生成Pockets:内加工路径

操作演示视频

b203881dd2413855863ea885aeee85a3.png程序框架

部分代码:

#include "mainwindow.h"
#include "ui_mainwindow.h"


using namespace Eigen;
//构造函数
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // https://www.youtube.com/watch?v=2VIGb31iwds
    //设置页面
    ui->stackedWidget->setCurrentIndex(1);
    //实例化opencascade
    OpencascadeWidget = new Opencascade(this);
    ui->gridLayout_opencascade->addWidget(OpencascadeWidget);//显示到界面
    //定时器更新opencascade
    QTimer *timer = new QTimer(this);
    connect(timer, &QTimer::timeout, this, &MainWindow::Update_Opencascade);
    timer->start(200);
    //关联按钮的信号与槽函数
    QObject::connect(ui->toolButton_edit_lead_in_out, SIGNAL(pressed()),SLOT(rotate_lead_in_out()));
    QObject::connect(ui->toolButton_add_operation, SIGNAL(pressed()),SLOT(add_operation()));
    QObject::connect(ui->toolButton_process_gcode, SIGNAL(pressed()),SLOT(process_operations()));
    QObject::connect(ui->toolButton_clear_operations, SIGNAL(pressed()),SLOT(clear_operations()));
}
//西沟函数//
MainWindow::~MainWindow()
{
    delete ui;
}
//添加操作
void MainWindow::add_operation(){
    gcode_get_user_settings(); //更新用户设置 Update gc.
    gcvec.push_back(gc);//添加到操作设置列表
    ui->listWidget->addItem(QString::fromStdString(gc.layer));//操作类型添加到列表
    process();
}
//生成Gcode
void MainWindow::process_operations(){
    linenumber=0; // 重置行号Reset gcode linenumber.
    gcode().clear();//清空gcode


    gc.operation_type="intro";//操作类型//
    gcode().generate();//生成//


    for(unsigned int i=0; i<gcvec.size(); i++){
        //为这个操作设置gcode参数.
        gc=gcvec.at(i);
        // Create offsets, pockets, etc.
        process();
        // Create gcode for this job.
        gcode().generate();
    }


    gc.operation_type="outtro";
    gcode().generate();


    gcode_preview();    // Update the mainwindow gcode preview:


    for(unsigned int i=0; i<rapidvec.size(); i++){
        OpencascadeWidget->show_shape(rapidvec.at(i).ashape); // Show gcode rapids.
    }
}
//清空操作
void MainWindow::clear_operations(){
    OpencascadeWidget->erase_all(); // Erases all content from the screen.
    contourvec.clear();
    pocketvec.clear();
    datavec.clear();
    rapidvec.clear();


    // 只在屏幕上绘制dxf数据:
    for(unsigned int i=0; i<dxfvec.size(); i++){
        OpencascadeWidget->show_shape(dxfvec.at(i).ashape); // Dxf drawing preview.
    }
    OpencascadeWidget->show_3d_interactive_box();


    gcvec.clear();
    ui->listWidget->clear();
    gcode().clear(); // Empty gcode.ngc file
    gcode_preview(); // Preview empty gcode.ngc file
}
//定时更新opencascade
void MainWindow::Update_Opencascade()
{
    OpencascadeWidget->Redraw();
}
//打开dxf文件
bool MainWindow::open_dxf_file(std::string filename){


    // OpencascadeWidget->erase_all();
    contourvec.clear();
    pocketvec.clear();
    datavec.clear();
    dxfvec.clear();
    rapidvec.clear();
    ui->comboBox_layer->clear();//清空dxf的图层
    dx_iface().clear(&fData);           //清除以前加载的dxf数据。 Clear previous loaded dxf data.


    bool ok = iface->fileImport( filename, &fData );
    if (!ok) {
        std::cout << "Error reading file " << filename << std::endl;
    } else {
        std::cout << "Ok reading file " << filename << std::endl;


        //根据dfx数据 生成opencascade图元  Process opencascade primitives.
        load_opencascade_primitives();
        OpencascadeWidget->zoom_all();//显示所有//
    }
    return ok;
}
//保存dxf文件
bool MainWindow::save_dxf_file(std::string filename){


    bool ok = iface->fileExport(filename, DRW::AC1027 , false, &fData);
    if (!ok) {
        std::cout << "Error saving file " << filename << std::endl;
    } else {
        std::cout << "Ok saving file " << filename << std::endl;
    }
    return ok;
}


//! Example how to write a primitive to the dxf file.
//! entity:图形的实际对象数据和图形实体。这可以包括原始数据,例如,圆实体是由其厚度,中心点,其半径和拉伸方向定义的。
bool MainWindow::write_entity(){


    std::cout<<"add line item"<<std::endl;
    DRW_Line testline;
    testline.basePoint.x = 10;
    testline.basePoint.y = 20;
    testline.secPoint.x = 30;
    testline.secPoint.y = 30;
    iface->addLine(testline);//添加直线
    return 1;
}
//加载opencascade图元
void MainWindow::load_opencascade_primitives(){


    // 显示dxf输出Print the dxf output.
    auto blocks = fData.mBlock->ent; //获得块  包含构成图形中每个块参考的图形对象和图形实体。
    for (auto iter = blocks.begin(); iter != blocks.end(); iter++){
        //绘制点,转换为AIS_Shape
        if(DRW::POINT == (*iter)->eType){ // std::cout<<"point"<<std::endl;


            DRW_Point *point = dynamic_cast<DRW_Point*>(*iter);
            Handle(AIS_Shape) ashape=draw_primitives().draw_3d_point({point->basePoint.x,point->basePoint.y,point->basePoint.z});
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::point;
            d.start={point->basePoint.x,point->basePoint.y,point->basePoint.z};
            d.end={point->basePoint.x,point->basePoint.y,point->basePoint.z};
            d.acad_layer=point->layer;
            dxfvec.push_back(d);
        }
        //绘制线
        if(DRW::LINE == (*iter)->eType){


            DRW_Line *line = dynamic_cast<DRW_Line*>(*iter);
            Handle(AIS_Shape) ashape=draw_primitives().draw_3d_line({line->basePoint.x, line->basePoint.y, line->basePoint.z},{line->secPoint.x, line->secPoint.y, line->secPoint.z});
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::line;
            d.start={line->basePoint.x, line->basePoint.y, line->basePoint.z};
            // Line middle-point, half-way point.
            d.control.push_back({(line->basePoint.x+line->secPoint.x)/2, (line->basePoint.y+line->secPoint.y)/2,(line->basePoint.z+line->secPoint.z)/2});
            // std::cout<<"controlpoint line x:"<<d.control.back().X()<<" y:"<<d.control.back().Y()<<" z:"<<d.control.back().Z()<<std::endl;
            d.end={line->secPoint.x, line->secPoint.y, line->secPoint.z};
            d.acad_layer=line->layer;
            dxfvec.push_back(d);
        }


        //绘制多边形 Lwpolyline is saved as clockwise [cw]
        if(DRW::LWPOLYLINE == (*iter)->eType){ // std::cout<<"lwpolyline"<<std::endl;


            DRW_LWPolyline *lwpolyline = dynamic_cast<DRW_LWPolyline*>(*iter);
            std::vector<gp_Pnt> pntvec;
            for(unsigned int i=0; i<lwpolyline->vertlist.size(); i++){
                pntvec.push_back({lwpolyline->vertlist.at(i)->x,lwpolyline->vertlist.at(i)->y,0});
            } // Close the polyline.
            pntvec.push_back({lwpolyline->vertlist.front()->x,lwpolyline->vertlist.front()->y,0});


            Handle(AIS_Shape) ashape=draw_primitives().draw_3d_line_wire(pntvec);
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            // Calculate if lwpolyline (wire) is cw or ccw. If area<0 => ccw. If area>0 => cw.
            double area=0;
            std::vector<gp_Pnt>::iterator it,it1;


            for(it=pntvec.begin(); it<pntvec.end()-1; it++){
                it1=it+1;
                area+=(it1->X()-it->X())*(it1->Y()+it->Y());
            }
            area=area/2; // Area / 2.
            // std::cout<<"lwpolyline area: "<<area<<std::endl; // https://www.youtube.com/watch?v=HG7I4oniOyA


            // If a ccw, invert to cw.
            if(area<0){
                std::reverse(pntvec.begin(),pntvec.end());
            }


            // Check output agian.
            area=0;
            for(it=pntvec.begin(); it<pntvec.end()-1; it++){
                it1=it+1;
                area+=(it1->X()-it->X())*(it1->Y()+it->Y());
            }
            area=area/2; // Area / 2.
            // std::cout<<"lwpolyline cw area : "<<area<<std::endl; // https://www.youtube.com/watch?v=HG7I4oniOyA


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::lwpolyline;


            d.start={pntvec.front().X(),pntvec.front().Y(),0};                      // std::cout<<"lwpolyline points x: "<<d.start.X()<<" y:"<<d.start.Y()<<" no z"<<std::endl;
            for(unsigned int i=1; i<pntvec.size()-1; i++){
                d.control.push_back({pntvec.at(i).X(),pntvec.at(i).Y(),0});         // std::cout<<"lwpolyline points x: "<<pntvec.at(i).X()<<" y:"<<pntvec.at(i).Y()<<" no z"<<std::endl;
            }
            d.end={pntvec.back().X(),pntvec.back().Y(),0};                          // std::cout<<"lwpolyline points x: "<<d.end.X()<<" y:"<<d.end.Y()<<" no z"<<std::endl;
            d.acad_layer=lwpolyline->layer;
            dxfvec.push_back(d);
        }


        // 绘制样条曲线 The spline has no direction just as the line.
        if(DRW::SPLINE == (*iter)->eType){ // std::cout<<"spline"<<std::endl;


            DRW_Spline *spline = dynamic_cast<DRW_Spline*>(*iter);
            std::vector<gp_Pnt> pntvec; // input
            for(unsigned int i=0; i<spline->controllist.size(); i++){
                pntvec.push_back({spline->controllist.at(i)->x,spline->controllist.at(i)->y,spline->controllist.at(i)->z});
            }
            Handle(AIS_Shape) ashape=draw_primitives().draw_3d_spline(pntvec,5);
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);
            OpencascadeWidget->show_shape(ashape);
            //std::cout<<"spline fitlist.size:"<<spline->fitlist.size()<<std::endl;
            //std::cout<<"spline controllist.size:"<<spline->controllist.size()<<std::endl;


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::spline;
            d.start={spline->controllist.front()->x,spline->controllist.front()->y,spline->controllist.front()->z};
            for(unsigned int i=1; i<spline->controllist.size()-1; i++){
                d.control.push_back({spline->controllist.at(i)->x,spline->controllist.at(i)->y,spline->controllist.at(i)->z});
            }
            d.end={spline->controllist.back()->x,spline->controllist.back()->y,spline->controllist.back()->z};
            d.acad_layer=spline->layer;
            dxfvec.push_back(d);
        }


        //绘制弧线 Arc's are saved as clockwise [cw] by draw_primivite->get points funtion !
        if(DRW::ARC == (*iter)->eType){ // std::cout<<"arc"<<std::endl;


            DRW_Arc *arc = dynamic_cast<DRW_Arc*>(*iter);
            Handle(AIS_Shape) ashape=draw_primitives().draw_2d_acad_arc({arc->center().x,arc->center().y,arc->center().z}, arc->radius(),
                                                                        arc->startAngle(),arc->endAngle());
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::arc;
            d.radius=arc->radious;
            d.center={arc->center().x,arc->center().y,arc->center().z};


            // Request a arc midpoint for the cavalier bulge function when we need 2 arc's to form a circle.
            int division=3;
            d.arcmid=draw_primitives().get_arc_circumfence_points({arc->center().x,arc->center().y,arc->center().z}, arc->radius(),
                                                                  arc->startAngle(),arc->endAngle(),division);
            // std::cout<<"arcmid.size, must be 1 controlpoint: "<<d.arcmid.size()<<std::endl;
            // std::cout<<"arcmid controlpoint x: "<<d.arcmid.at(1).X()<<" y:"<<d.arcmid.at(1).Y()<<" z:"<<d.arcmid.at(1).Z()<<std::endl;


            // Request a few arc circumfence points.
            division=8;
            d.control=draw_primitives().get_arc_circumfence_points({arc->center().x,arc->center().y,arc->center().z}, arc->radius(),
                                                                   arc->startAngle(),arc->endAngle(),division);


            d.start=d.control.front();  // std::cout<<"arc starpoint x:"<<d.start.X()<<" y:"<<d.start.Y()<<" z:"<<d.start.Z()<<std::endl;
            d.end=d.control.back();     // std::cout<<"arc endpoint x:"<<d.end.X()<<" y:"<<d.end.Y()<<" z:"<<d.end.Z()<<std::endl;


            // std::cout<<"arc startpoint x: "<<d.start.X()<<" y:"<<d.start.Y()<<" z:"<<d.start.Z()<<std::endl;
            // std::cout<<"arc endpoint x: "<<d.end.X()<<" y:"<<d.end.Y()<<" z:"<<d.end.Z()<<std::endl;
            d.control.pop_back();
            d.control.erase(d.control.begin());


            for(unsigned int i=0; i<d.control.size(); i++){
                //std::cout<<"arc controlpoints x:"<<d.control.at(i).X()<<" y:"<<d.control.at(i).Y()<<" z:"<<d.control.at(i).Z()<<std::endl;
            }
            d.acad_layer=arc->layer;
            dxfvec.push_back(d);
        }


        //绘制园 Circles are saved clockwise [cw], startpoint is right side of circle.
        if(DRW::CIRCLE == (*iter)->eType){  // std::cout<<"circle"<<std::endl;


            DRW_Circle *circle = dynamic_cast<DRW_Circle*>(*iter);
            Handle(AIS_Shape) ashape=draw_primitives().draw_2d_circle({circle->basePoint.x,circle->basePoint.y,circle->basePoint.z},circle->radious);
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::circle;
            d.radius=circle->radious;
            d.center={circle->basePoint.x,circle->basePoint.y,circle->basePoint.z};


            // For contour recognize we need a few circle circumfence points to perform the pip (point in polygon) algoritme.
            // Clockwise output, division (segmentation value) :
            int division=8;
            d.control=draw_primitives().get_cirlce_circumfence_points({circle->basePoint.x,circle->basePoint.y,circle->basePoint.z},circle->radious,division);


            d.start=d.control.front();
            d.end=d.control.back();


            d.control.pop_back();
            d.control.erase(d.control.begin());
            d.acad_layer=circle->layer;
            dxfvec.push_back(d);
        }


        //绘制椭圆 Ellipses are saved clockwise [cw], startpoint is secpoint.
        if(DRW::ELLIPSE == (*iter)->eType){ // std::cout<<"ellipse"<<std::endl;


            DRW_Ellipse *ellipse = dynamic_cast<DRW_Ellipse*>(*iter);


            // To be reviewed when we have more time:
            Handle(AIS_Shape) ashape=draw_primitives().draw_2d_ellipse({ellipse->basePoint.x,ellipse->basePoint.y,ellipse->basePoint.z},
                                                                       {ellipse->secPoint.x,ellipse->secPoint.y,ellipse->secPoint.z}, // offset from base
                                                                       ellipse->staparam,
                                                                       ellipse->endparam,
                                                                       ellipse->ratio);
            ashape=draw_primitives().colorize(ashape,Quantity_NOC_BLACK,1);


            // std::cout<<"ellipse secpoint x:"<<ellipse->secPoint.x<<" y:"<<ellipse->secPoint.y<<" z:"<<ellipse->secPoint.z<<std::endl;
            // std::cout<<"ellipse extpoint x:"<<ellipse->extPoint.x<<" y:"<<ellipse->extPoint.y<<" z:"<<ellipse->extPoint.z<<std::endl;


            datas d;
            d.ashape=ashape;
            d.primitivetype=primitive_type::ellipse;


            // Clockwise output, division (segmentation value) :
            int division=8;
            d.control=draw_primitives().get_ellipse_circumfence_points({ellipse->basePoint.x,ellipse->basePoint.y,ellipse->basePoint.z},
                                                                       {ellipse->secPoint.x,ellipse->secPoint.y,ellipse->secPoint.z}, // offset from base
                                                                       ellipse->staparam,
                                                                       ellipse->endparam,
                                                                       ellipse->ratio,division);


            d.start=d.control.front();
            d.end=d.control.back();


            d.control.pop_back();
            d.control.erase(d.control.begin());
            d.acad_layer=ellipse->layer;
            dxfvec.push_back(d);


            // Acad's ellipse nr's, https://github.com/grotius-cnc/cadcam/blob/master/dxf/read_ellipse_AC1027.cpp
            // x,y,z centerpoint    10,20,30
            // x,y,z endpoint mayor 11,21,31 ( coordinates relative to ellipse centerpoint..)
            // ratio                40
            // start angle          41
            // end angle            42
        }
    }




    std::vector<std::string>layervec;//图层名矢量
    for(unsigned int i=0; i<dxfvec.size(); i++){
        // Preview primairy dxf data.
        OpencascadeWidget->show_shape(dxfvec.at(i).ashape);//预览图元dxf数据
        // List cad_layers.
        std::string layer=dxfvec.at(i).acad_layer;//获取图元的cad层名
        // No duplicates
        if(std::find(layervec.begin(), layervec.end(),layer)!=layervec.end()){
            // Do nothing
        } else {
            layervec.push_back(layer);
        }
    }


    //填充图层组合框 Populate the layer combobox.
    for(unsigned int i=0; i<layervec.size(); i++){
        ui->comboBox_layer->addItem(QString::fromStdString(layervec.at(i)));
    }
}


//! This function is a buttonpress slot.
//! 按钮按下槽函数 process
void MainWindow::process(){


    contourvec.clear();//外加工轮廓清空
    pocketvec.clear();//内加工轮廓清空
    datavec.clear();//dxf数据清空


    // Check what user has selected. Did he select the combobox [offset] or [pocket] item?
    //检查用户选择了什么。他选择了组合框[偏移]还是[口袋]项目?
    if(gc.operation_type=="contour"){
        generate_contours();//生成外加工轮廓
    }
    if(gc.operation_type=="pocket"){
        generate_pockets();//生成内加工轮廓
    }
}


//! Class to perform pockets. With or without islands.
//! 类来执行口袋。有或没有岛屿。
void MainWindow::generate_pockets(){
    // Finding contourpoints hit tollerance in mm.
    // The function also calculates the "depth sequence" and the "keep parts together" algoritme.
    //查找轮廓点命中公差mm。
    //函数还计算“深度序列”和“保持part在一起”算法。
    contours().main(0.1, gc.layer);
    // Stay with cw contours. We need cw contour for islands.
    //保持cw轮廓。我们需要cw轮廓的岛屿。
    offsets().do_pocket();


    for(unsigned int i=0; i<dxfvec.size(); i++){
        OpencascadeWidget->show_shape(dxfvec.at(i).ashape); //Dxf绘图预览                            // Dxf drawing preview.
    }


    for(unsigned int i=0; i<pocketvec.size(); i++){
        for(unsigned int j=0; j<pocketvec.at(i).offset_sequence.size(); j++){   //预览口袋偏移轮廓数据               // Offset contour data.
            OpencascadeWidget->show_shape(pocketvec.at(i).offset_sequence.at(j).ashape);
        }
    }
    //显示交互box
    OpencascadeWidget->show_3d_interactive_box();
}


//! Class to perform offsets. 执行偏置:外加工轮廓
void MainWindow::generate_contours(){


    //寻找轮廓 点击中公差 毫米 Finding contourpoints hit tollerance in mm.
    contours().main(0.1, gc.layer);//轮廓偏移0.1mm
    //变形cw成ccw轮廓奇数的深度。 Morph cw into ccw contours for the odd depth's.
    contours().add_contour_ccw();


    // 生成偏置 Generate offsets.
    offsets().do_offset(gc.offset,offset_action::offset_contour,gc.lead_in,gc.lead_out);
    offsets().do_offset(gc.offset,offset_action::lead_base_contour,gc.lead_in,gc.lead_out);//每个轮廓都会有的基本路径
    offsets().do_offset(gc.offset,offset_action::lead_in_contour,gc.lead_in,gc.lead_out);
    offsets().do_offset(gc.offset,offset_action::lead_out_contour,gc.lead_in,gc.lead_out);


    for(unsigned int i=0; i<dxfvec.size(); i++){
        OpencascadeWidget->show_shape(dxfvec.at(i).ashape);  //显示dxf数据                                   // Dxf drawing preview.
    }


    for(unsigned int i=0; i<contourvec.size(); i++){
        for(unsigned int j=0; j<contourvec.at(i).offset_sequence.size(); j++){    //显示外加工轮廓              // Offset contour data.
            OpencascadeWidget->show_shape(contourvec.at(i).offset_sequence.at(j).ashape);
        }
    }


    for(unsigned int i=0; i<contourvec.size(); i++){//显示外加工轮廓的导入和导出
        OpencascadeWidget->show_shape(contourvec.at(i).lead_in.ashape);                         // Show lead-in, lead-out shapes.
        OpencascadeWidget->show_shape(contourvec.at(i).lead_out.ashape);
    }
    //显示交互框
    OpencascadeWidget->show_3d_interactive_box();
}


//! Move the lead_in-out to next position of the contourvec.at[i]. We simply rotote the primitive sequence vector +1.
//! Then we perform a new contour offset and reload the opencascade view. The gcode output .ngc file is updated.
//!移动lead_in-out到contourvec.at[i]的下一个位置。我们简单地旋转原始序列向量+1。
//!然后我们执行一个新的轮廓偏移并重新opencascade视图。更新gcode输出的.ngc文件。
void MainWindow::rotate_lead_in_out(){


    rapidvec.clear();


    OpencascadeWidget->erase_all();//清空场景
    unsigned int i=OpencascadeWidget->selected_contour;//获取选中轮廓索引
    //清空第i个轮廓的 偏置序列、基本路径、引入路径、退出路径
    for(unsigned int i=0; i<contourvec.size(); i++){                                            // Remove all offsets.
        contourvec.at(i).offset_sequence.clear();
        contourvec.at(i).lead_base.points.clear();
        contourvec.at(i).lead_in.points.clear();
        contourvec.at(i).lead_out.points.clear();
    }
    //获取gcode设置
    gcode_get_user_settings();
    double offset=gc.offset;    //更新偏置设置                                                               // Gc = gcode setup.
    double lead_in=gc.lead_in;  //更新进刀量
    double lead_out=gc.lead_out;//更新退刀量
    //重新偏置第i个轮廓,生成新的路径
    offsets().rotate_primairy_contour(i);                                                       // Rotate selected contour +1.
    offsets().do_offset(offset,offset_action::offset_contour,lead_in,lead_out);                 // Create new offsets.
    offsets().do_offset(offset,offset_action::lead_base_contour,lead_in,lead_out);
    offsets().do_offset(offset,offset_action::lead_in_contour,lead_in,lead_out);
    offsets().do_offset(offset,offset_action::lead_out_contour,lead_in,lead_out);


    linenumber=0; // 重置行号Reset gcode linenumber.
    gcode().clear();
    //重新生成每个操作类型的gcode
    gc.operation_type="intro";
    gcode().generate();


    gc.operation_type="pocket";
    gcode().generate();


    gc.operation_type="contour";
    gcode().generate();                                                                         // Generate gcode.


    gc.operation_type="outtro";
    gcode().generate();  // Generate gcode.


    //更新主窗体gcode视图 Update the mainwindow gcode preview:
    gcode_preview();
    //显示dxf数据
    for(unsigned int i=0; i<dxfvec.size(); i++){
        OpencascadeWidget->show_shape(dxfvec.at(i).ashape);                                     // Dxf drawing preview.
    }
    //显示外加工轮廓数据
    for(unsigned int i=0; i<contourvec.size(); i++){
        for(unsigned int j=0; j<contourvec.at(i).offset_sequence.size(); j++){                  // Offset contour data.
            OpencascadeWidget->show_shape(contourvec.at(i).offset_sequence.at(j).ashape);
        }
    }
    //显示外加工轮廓的 进刀路劲和退刀路径
    for(unsigned int i=0; i<contourvec.size(); i++){
        OpencascadeWidget->show_shape(contourvec.at(i).lead_in.ashape);                         // Show lead-in, lead-out shapes.
        OpencascadeWidget->show_shape(contourvec.at(i).lead_out.ashape);
    }
    //显示填充路径
    for(unsigned int i=0; i<pocketvec.size(); i++){
        for(unsigned int j=0; j<pocketvec.at(i).offset_sequence.size(); j++){                  // Offset contour data.
            OpencascadeWidget->show_shape(pocketvec.at(i).offset_sequence.at(j).ashape);
        }
    }
    //显示 空程路径
    for(unsigned int i=0; i<rapidvec.size(); i++){
        OpencascadeWidget->show_shape(rapidvec.at(i).ashape);                                   // Show gcode rapids.
    }
    //显示交互框
    OpencascadeWidget->show_3d_interactive_box();
}
//获取用户设置
void MainWindow::gcode_get_user_settings(){


    gc.linenumber_format=ui->lineEdit_gcode_linenumber_format->text().toStdString();
    gc.print_linenumbers=ui->radioButton_use_line_numbers->isChecked();
    gc.feedrate=ui->lineEdit_gcode_feedrate->text().toDouble();
    gc.power=ui->lineEdit_gcode_power->text().toDouble();
    gc.lead_in=ui->lineEdit_lead_in->text().toDouble();
    gc.lead_out=ui->lineEdit_lead_out->text().toDouble();
    gc.travelheight=ui->lineEdit_travel_height->text().toDouble();
    gc.pierceheight=ui->lineEdit_plunge_height->text().toDouble();
    gc.piercespeed=ui->lineEdit_plunge_speed->text().toDouble();
    gc.piercedelay=ui->lineEdit_plunge_delay->text().toDouble();
    gc.offset=ui->lineEdit_offset->text().toDouble();
    gc.layer=ui->comboBox_layer->currentText().toStdString();
    gc.internal_pocket_offset=ui->lineEdit_pocket_internal_offset->text().toDouble();
    gc.z_axis_format=ui->lineEdit_z_axis_format->text().toStdString();
    gc.tooloffset_x=ui->lineEdit_tooloffset_x->text().toDouble();
    gc.tooloffset_y=ui->lineEdit_tooloffset_y->text().toDouble();
    gc.tooloffset_z=ui->lineEdit_tooloffset_z->text().toDouble();
    gc.tool_on_macro=ui->lineEdit_tool_on_macro->text().toStdString();


    //Gcode的开始程序 Intro
    QString plainTextEditContents = ui->plainTextEdit_intro->toPlainText();
    QStringList lines = plainTextEditContents.split("\n");
    gc.intro.clear();
    for(int i=0; i<lines.size(); i++){
        std::string str=lines.at(i).toStdString();
        str+="\n";
        gc.intro.push_back(str);
    }
    //Gcode的结束程序 Outtro
    gc.outtro.clear();
    plainTextEditContents = ui->plainTextEdit_outtro->toPlainText();
    lines = plainTextEditContents.split("\n");
    for(int i=0; i<lines.size(); i++){
        std::string str=lines.at(i).toStdString();
        str+="\n";
        gc.outtro.push_back(str);
    }


    //操作类型 Operation type, contour, pocket, drill.
    gc.operation_type=ui->comboBox_operation_type->currentText().toStdString();
}
//打开gcode文件预览Gcode
void MainWindow::gcode_preview()
{
    std::string line,lines;
    std::ifstream myfile ("gcode.ngc");//文件名
    if (myfile.is_open())//打开gcode
    {
        while ( getline (myfile,line) )
        {
            lines+=line;
            lines+="\n";
        }
        myfile.close();
    }
    else std::cout << "Unable to open file";
    //显示gcode
    ui->plainTextEdit_gcode->setPlainText(QString::fromStdString(lines));
}
//打开dxf文件
void MainWindow::on_toolButton_open_dxf_pressed(){
    if (!pfd::settings::available()){
        std::cout << "Portable File Dialogs are not available on this platform. \n"
                     "On linux install zenity, $ sudo apt-get install zenity\n";
    }
    auto f = pfd::open_file("Choose files to read", DEFAULT_PATH,
                            { "Dxf Files (.dxf)", "*.dxf",
                              "All Files", "*" }, pfd::opt::none); // Or ::multiselect.
    open_dxf_file(f.result().at(0)); // This lib can open multiple results.
}


//void MainWindow::on_toolButton_save_dxf_pressed()
//{
//    std::string filename=ui->lineEdit_dxf_filename->text().toStdString();
//    save_dxf_file(filename);
//}


//void MainWindow::on_toolButton_add_line_pressed()
//{
//    write_entity();
//}


//void MainWindow::on_toolButton_stacket_page_plus_pressed()
//{
//    if(ui->stackedWidget->currentIndex() != ui->stackedWidget->count()-1){
//        ui->stackedWidget->setCurrentIndex(ui->stackedWidget->currentIndex()+1);
//    } else {


//        ui->stackedWidget->setCurrentIndex(0);
//    }
//    // std::cout<<"curindex:"<<ui->stackedWidget->currentIndex()<<std::endl;
//}

扩展阅读:

DXF文件格式理解

https://www.cnblogs.com/MakeView660/p/12341337.html

可移植的GUI对话框库,c++ 11,单头文件

https://github.com/samhocevar/portable-file-dialogs

ubuntu 安装opencasecade

https://blog.csdn.net/weixin_43581274/article/details/116567457

ubuntu安装KDL运动学库

https://blog.csdn.net/hellohake/article/details/114874014

The End

  • 1
    点赞
  • 15
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Qt是一个跨平台的C++应用程序框架,可以用于开发图形界面和多种功能的软件。而DXF是一种用于交换CAD数据的文件格式,常用于绘图软件之间的数据传输。 在Qt中导入DXF库,可以通过以下几个步骤实现: 1. 下载DXF库:首先需要找到一个适用于QtDXF库,并下载到本地。 2. 配置项目:打开Qt项目,将下载的DXF库导入到项目的文件夹中,并在项目的.pro文件中进行相关配置,例如添加库的引用、设置头文件路径等。 3. 包含头文件:在需要使用DXF功能的源文件中,包含相关的头文件,以便能够调用DXF库中的函数和类。 4. 编写代码:根据自己的需求,编写与DXF文件相关的代码,例如读取DXF文件内容、绘制图形、修改数据等。 5. 运行程序:编译并运行程序,查看结果是否符合预期。 需要注意的是,导入DXF库可能涉及到一些平台相关的配置,例如在Windows下可能需要将库文件添加到系统的环境变量中,或者配置库文件路径,以保证程序能够正确地找到依赖的文件。 综上所述,Qt与导入DXF库可以实现在Qt项目中读取和处理DXF文件的功能,通过配置项目、包含头文件、编写相关代码可以实现对DXF文件的读取和操作。这样就可以在Qt开发出更加强大和灵活的CAD或绘图软件。 ### 回答2: Qt是一个跨平台的C++应用程序开发框架,而导入dxf库是指将DXF文件(Drawing Interchange Format,绘图交换格式)导入到应用程序中进行处理。 在Qt中导入dxf库的主要目的是为了处理和解析DXF文件,以便能够提取出其中的绘图数据并在应用程序中进行展示或进一步处理。常见的dxf库包括libdxfrw和OpenCascade等。 使用Qt导入dxf库的好处是可以利用Qt的多种功能和工具来处理和展示DXF文件中的内容。Qt提供了丰富的图形绘制功能,可以将DXF文件中的绘图数据绘制到界面上,同时也提供了图形交互和事件处理等功能。此外,Qt还支持多线程和跨平台开发,可以轻松地将dxf库集成到不同操作系统中的应用程序中。 使用dxf库导入DXF文件的好处是可以方便地解析DXF文件的结构和内容。DXF是一种开放的文件格式,广泛应用于CAD软件中,通过导入dxf库,开发者可以轻松解析DXF文件中的实体、图层、颜色、线型等信息,从而能够更好地理解和处理DXF文件的内容。 总结来说,Qt与导入dxf库是相互配合的,Qt提供了强大的开发框架和工具,而导入dxf库可以方便地处理和解析DXF文件。通过二者的结合,开发者可以在Qt应用程序中实现对DXF文件的加载、解析、展示和处理,从而满足各种个性化的需求。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值