Frontend to the famous GRBL.

hpglparser.cpp 14KB

    /* Part of x2grbl * * Copyright Johann Wilhelm <johann.wilhelm@9mal6.de> 2015 * * see Readme.md for detailed license and usage information! */ #include "hpglparser.h" #include <QTextStream> #include <QStringList> #include <QDebug> #include <QRegExp> #include <QRect> #include <QRectF> #include <QPointF> #include <QSettings> #include <QDebug> #include <QVector2D> HpglParser::HpglParser() { dpi=1016;//25um useJKforArcs=true; addRadiusForJKArcs=false; x=0; y=0; z=0; ResetCfg(); } bool HpglParser::open(QIODevice &Input) { GCodeListing.clear(); ResetCfg(); x=0; y=0; z=0; QSettings settings(QSettings::IniFormat, QSettings::UserScope, QString("2.5d Grbl-Commander")); highZ=1; lowZ=-.1; useJKforArcs=true; addRadiusForJKArcs=false; settings.beginGroup("Hpgl"); if (settings.contains(QString("HighZ"))) highZ=settings.value("HighZ").toDouble(); if (settings.contains(QString("LowZ"))) lowZ=settings.value("LowZ").toDouble(); if (settings.contains(QString("UseJKforArcs"))) useJKforArcs=settings.value("UseJKforArcs").toBool(); if (settings.contains(QString("AddRadiusForJKArcs"))) addRadiusForJKArcs=settings.value("AddRadiusForJKArcs").toBool(); settings.endGroup(); z=highZ; //just to be safe... QRegExp CommandParser(QString("([A-Z][A-Z][^;]*;)")); QRegExp ParameterParser(QString("([A-Z][A-Z])([^;]+)*;")); if (Input.isOpen()) { QTextStream InputStream(&Input); while (!InputStream.atEnd()) { QString Line=InputStream.readLine(); int pos=0; while (pos >= 0) { pos=CommandParser.indexIn(Line, pos); if (pos >= 0) { QStringList Matches=CommandParser.capturedTexts(); for (int i=1;i<Matches.count();i++) { ParameterParser.indexIn(Matches[i], 0); QStringList Parts=ParameterParser.capturedTexts(); if (!ExecuteCmd(Parts[1], Parts[2].trimmed())) { qDebug()<<"Error parsing HPGL "<<Matches[i]<<"\n"; return false; } //qDebug()<<Matches[i]<<"\n"; } pos++; } } } } return true; } void HpglParser::ResetCfg() { absolutePlotting=true; scalingX=1; scalingY=1; } bool HpglParser::ExecuteCmd(QString Cmd, QString Params) { double Hpgl2mm=25.4/dpi; if (Cmd==QString("DF")) { ResetCfg(); } else if (Cmd==QString("IN")) { ResetCfg(); } else if (Cmd==QString("IP")) { QStringList Coords=Params.split(QChar(',')); if (Coords.count()==4) { scalingPoint1=QPoint(Coords[0].toInt(), Coords[1].toInt()); scalingPoint2=QPoint(Coords[2].toInt(), Coords[3].toInt()); } else if (Coords.count()==2) { QPoint Tmp=scalingPoint2-scalingPoint1; scalingPoint1=QPoint(Coords[0].toInt(), Coords[1].toInt()); scalingPoint2=Tmp+scalingPoint1; } else { qDebug()<<"Wrong Parameters given for command IP!\n"; return false; } } else if (Cmd==QString("SC")) { if (Params.isEmpty()) { scalingX=1; scalingY=1; } else { QStringList Coords=Params.split(QChar(',')); if (Coords.count()==4) { QRectF Tmp=QRectF(QPointF(Coords[0].toDouble(), Coords[2].toDouble()), QPointF(Coords[1].toDouble(), Coords[3].toDouble())); QRectF ScaleRect=QRectF(scalingPoint1, scalingPoint2); scalingX=Tmp.width()/ScaleRect.width(); scalingY=Tmp.height()/ScaleRect.height(); } else { qDebug()<<"Wrong Parameters given for command SC!\n"; return false; } } } else if (Cmd==QString("IW")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("RO")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("PG")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("PU")) { z=highZ; GCode Code; Code.Cmd=1; Code.Code=CodeType_GCode; Code.Parameters["Z"]=QString("%1").arg(z); Code.Comment="PD"; GCodeListing.append(Code); QStringList Coords=Params.split(QChar(',')); if (Coords.count()%2==0) { const int CoordsPairs=Coords.count()/2; for (int i=0;i<CoordsPairs;i++) { if (absolutePlotting) { x=Coords[i*2+0].toInt(); y=Coords[i*2+1].toInt(); } else { x+=Coords[i*2+0].toInt(); y+=Coords[i*2+1].toInt(); } Code.Parameters.clear(); Code.Comment=QString("%1 %2").arg(x).arg(y); Code.Parameters["X"]=QString("%1").arg(x*Hpgl2mm); Code.Parameters["Y"]=QString("%1").arg(y*Hpgl2mm); GCodeListing.append(Code); } } else if (!Params.isEmpty()){ qDebug()<<"Wrong number of Coordinates for PU!\n"; return false; } } else if (Cmd==QString("PD")) { z=lowZ; GCode Code; Code.Cmd=1; Code.Code=CodeType_GCode; Code.Parameters["Z"]=QString("%1").arg(z); Code.Comment="PD"; GCodeListing.append(Code); QStringList Coords=Params.split(QChar(',')); if (Coords.count()%2==0) { const int CoordsPairs=Coords.count()/2; for (int i=0;i<CoordsPairs;i++) { if (absolutePlotting) { x=Coords[i*2+0].toInt(); y=Coords[i*2+1].toInt(); } else { x+=Coords[i*2+0].toInt(); y+=Coords[i*2+1].toInt(); } Code.Parameters.clear(); Code.Comment=QString("%1 %2").arg(x).arg(y); Code.Parameters["X"]=QString("%1").arg(x*Hpgl2mm*scalingX); Code.Parameters["Y"]=QString("%1").arg(y*Hpgl2mm*scalingY); GCodeListing.append(Code); } } else if (!Params.isEmpty()){ qDebug()<<"Wrong number of Coordinates for PD!\n"; return false; } } else if (Cmd==QString("PA")) { GCode Code; Code.Cmd=1; Code.Code=CodeType_GCode; QStringList Coords=Params.split(QRegExp("[, ]")); if (Coords.count()==2) { x=Coords[0].toInt(); y=Coords[1].toInt(); Code.Parameters["X"]=QString("%1").arg(x*Hpgl2mm*scalingX); Code.Parameters["Y"]=QString("%1").arg(y*Hpgl2mm*scalingY); GCodeListing.append(Code); } else { qDebug()<<"Wrong number of Coordinates for PA!\n"; return false; } } else if (Cmd==QString("PR")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("AA")) { QStringList Coords=Params.split(QChar(',')); if (Coords.count()==3) { GCode Code; Code.Code=CodeType_GCode; Code.Cmd=17; //select xy-plane for cirlce GCodeListing.append(Code); Code.Cmd=2; if (Coords[2]==QString("360")) { if (useJKforArcs) { QVector2D A=QVector2D(x,y); //Current Position QVector2D C=QVector2D(Coords[0].toDouble(), Coords[1].toDouble()); //Center QVector2D Offset=C-A; Code.Parameters["I"]=QString("%1").arg(Offset.x()*Hpgl2mm*scalingX); Code.Parameters["J"]=QString("%1").arg(Offset.y()*Hpgl2mm*scalingY); if (addRadiusForJKArcs) { A-=C; double r=A.length(); Code.Parameters["r"]=QString("%1").arg(r*Hpgl2mm*scalingX); } GCodeListing.append(Code); //no change...just a circle x=x; y=y; } } else { double qc=Coords[2].toDouble()/180.0*M_PI; //>0 => ccw if (qc>0) Code.Cmd=3; QVector2D A=QVector2D(x,y); //Current Position QVector2D B; //resulting point... QVector2D C=QVector2D(Coords[0].toDouble(), Coords[1].toDouble()); //Center A-=C; //Move coordinate-system to the center double r=A.length(); qDebug()<<"r="<<r*Hpgl2mm*scalingX<<"\n"; double alpha=acos(A.x()/r); //coordinate-transform.... A(x,y)->A(alpha,r) if (A.y()<0) alpha*=-1; B=QVector2D(cos(alpha+qc), sin(alpha+qc))*r; B+=C; //Move coordinate-system back... if (useJKforArcs) { QVector2D Offset=-A; Code.Parameters["X"]=QString("%1").arg(B.x()*Hpgl2mm*scalingX); Code.Parameters["Y"]=QString("%1").arg(B.y()*Hpgl2mm*scalingY); Code.Parameters["I"]=QString("%1").arg(Offset.x()*Hpgl2mm*scalingX); Code.Parameters["J"]=QString("%1").arg(Offset.y()*Hpgl2mm*scalingY); if (addRadiusForJKArcs) Code.Parameters["r"]=QString("%1").arg(r*Hpgl2mm*scalingX); } else { Code.Parameters["X"]=QString("%1").arg(B.x()*Hpgl2mm*scalingX); Code.Parameters["Y"]=QString("%1").arg(B.y()*Hpgl2mm*scalingY); Code.Parameters["r"]=QString("%1").arg(r*Hpgl2mm*scalingX); } GCodeListing.append(Code); x=B.x(); y=B.y(); } } else { qDebug()<<"Wrong number of Coordinates for AA!\n"; return false; } } else if (Cmd==QString("AR")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("CI")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("EA")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("ER")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("EW")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("RA")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("RR")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("WG")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("FT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("LT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("PW")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SM")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SP")) { pen=Params.toInt(); //todo check for int 0-6 return true; } else if (Cmd==QString("TL")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("XT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("YT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("PT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("CS")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("CA")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SS")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SA")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("DT")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("LB")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("DI")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("DR")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("CP")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SI")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SR")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("SL")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else if (Cmd==QString("UC")) { qDebug()<<"Not implemented Command "<<Cmd<<"!\n"; return false; } else { qDebug()<<"Unknown Command "<<Cmd<<"!\n"; return false; } return true; } void HpglParser::InitParser(GCodeParser &Parser) { Parser.Lines.clear(); const int count=GCodeListing.count(); for (int i=0;i<count;i++) { Parser.Lines.insert(i+1,GCodeListing[i].serialize()); } }