Download src/Mod/CAM/PathSimulator/AppGL/GCodeParser.cpp from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 7.11 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathSimulator/AppGL/GCodeParser.cpp
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/CAM/PathSimulator/AppGL/GCodeParser.cpp
-
curl -L -o GCodeParser.cpp https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/CAM/PathSimulator/AppGL/GCodeParser.cpp
7.11 kB
| // SPDX-License-Identifier: LGPL-2.1-or-later | |
| /*************************************************************************** | |
| * Copyright (c) 2024 Shai Seger <shaise at gmail> * | |
| * * | |
| * This file is part of the FreeCAD CAx development system. * | |
| * * | |
| * This library is free software; you can redistribute it and/or * | |
| * modify it under the terms of the GNU Library General Public * | |
| * License as published by the Free Software Foundation; either * | |
| * version 2 of the License, or (at your option) any later version. * | |
| * * | |
| * This library is distributed in the hope that it will be useful, * | |
| * but WITHOUT ANY WARRANTY; without even the implied warranty of * | |
| * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * | |
| * GNU Library General Public License for more details. * | |
| * * | |
| * You should have received a copy of the GNU Library General Public * | |
| * License along with this library; see the file COPYING.LIB. If not, * | |
| * write to the Free Software Foundation, Inc., 59 Temple Place, * | |
| * Suite 330, Boston, MA 02111-1307, USA * | |
| * * | |
| ***************************************************************************/ | |
| using namespace MillSim; | |
| static char TokTypes[] = "GTXYZIJKR"; | |
| GCodeParser::~GCodeParser() | |
| { | |
| // Clear the vector | |
| Operations.clear(); | |
| } | |
| bool GCodeParser::Parse(const char* filename) | |
| { | |
| Operations.clear(); | |
| lastState = {eNop, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0}; | |
| lastTool = -1; | |
| FILE* fl; | |
| if ((fl = fopen(filename, "rt")) == nullptr) { | |
| return false; | |
| } | |
| char line[120]; | |
| while (!feof(fl)) { | |
| if (fgets(line, 120, fl) != NULL) { | |
| AddLine(line); | |
| } | |
| } | |
| fclose(fl); | |
| return false; | |
| } | |
| const char* GCodeParser::GetNextToken(const char* ptr, GCToken* token) | |
| { | |
| float tokval; | |
| token->letter = '*'; | |
| while (*ptr != 0) { | |
| char letter = toupper(*ptr); | |
| ptr++; | |
| if (letter == ' ') { | |
| continue; | |
| } | |
| if (letter == '(') { | |
| break; | |
| } | |
| if (IsValidToken(letter)) { | |
| ptr = ParseFloat(ptr, &tokval); | |
| token->letter = letter; | |
| token->fval = tokval; | |
| token->ival = (int)(tokval + 0.5); | |
| break; | |
| } | |
| } | |
| return ptr; | |
| } | |
| bool GCodeParser::IsValidToken(char tok) | |
| { | |
| int len = (int)strlen(TokTypes); | |
| for (int i = 0; i < len; i++) { | |
| if (tok == TokTypes[i]) { | |
| return true; | |
| } | |
| } | |
| return false; | |
| } | |
| const char* GCodeParser::ParseFloat(const char* ptr, float* retFloat) | |
| { | |
| float decPos = 10; | |
| float sign = 1; | |
| bool decimalPointFound = false; | |
| float res = 0; | |
| while (*ptr != 0) { | |
| char letter = toupper(*ptr); | |
| ptr++; | |
| if (letter == ' ') { | |
| continue; | |
| } | |
| if (letter == '-') { | |
| sign = -1; | |
| } | |
| else if (letter == '.') { | |
| decimalPointFound = true; | |
| } | |
| else if (letter >= '0' && letter <= '9') { | |
| float digitVal = (float)(letter - '0'); | |
| if (decimalPointFound) { | |
| res = res + digitVal / decPos; | |
| decPos *= 10; | |
| } | |
| else { | |
| res = res * 10 + digitVal; | |
| } | |
| } | |
| else { | |
| ptr--; | |
| break; | |
| } | |
| } | |
| *retFloat = res * sign; | |
| return ptr; | |
| } | |
| bool GCodeParser::ParseLine(const char* ptr) | |
| { | |
| // Truncate at first semicolon (annotations / comment) | |
| const char* comment = strchr(ptr, ';'); | |
| std::string line; | |
| if (comment) { | |
| line = std::string(ptr, comment - ptr); | |
| ptr = line.c_str(); | |
| } | |
| GCToken token; | |
| bool validMotion = false; | |
| bool exitLoop = false; | |
| int cmd = 0; | |
| while (*ptr != 0 && !exitLoop) { | |
| ptr = GetNextToken(ptr, &token); | |
| lastLastState = lastState; | |
| switch (token.letter) { | |
| case '*': | |
| exitLoop = true; | |
| break; | |
| case 'G': | |
| cmd = token.ival; | |
| if (cmd == 0 || cmd == 1) { | |
| lastState.cmd = eMoveLiner; | |
| } | |
| else if (cmd == 2) { | |
| lastState.cmd = eRotateCW; | |
| } | |
| else if (cmd == 3) { | |
| lastState.cmd = eRotateCCW; | |
| } | |
| else if (cmd == 73 || cmd == 81 || cmd == 82 || cmd == 83) { | |
| lastState.cmd = eDril; | |
| lastState.retract_z = lastState.z; | |
| } | |
| else if (cmd == 98 || cmd == 99) { | |
| lastState.retract_mode = cmd; | |
| } | |
| else if (cmd == 80) { | |
| lastState.retract_mode = 0; | |
| } | |
| break; | |
| case 'T': | |
| lastState.tool = token.ival; | |
| break; | |
| case 'X': | |
| lastState.x = token.fval; | |
| validMotion = true; | |
| break; | |
| case 'Y': | |
| lastState.y = token.fval; | |
| validMotion = true; | |
| break; | |
| case 'Z': | |
| lastState.z = token.fval; | |
| validMotion = true; | |
| break; | |
| case 'I': | |
| lastState.i = token.fval; | |
| break; | |
| case 'J': | |
| lastState.j = token.fval; | |
| break; | |
| case 'K': | |
| lastState.k = token.fval; | |
| break; | |
| case 'R': | |
| lastState.r = token.fval; | |
| break; | |
| } | |
| } | |
| return validMotion; | |
| } | |
| bool GCodeParser::AddLine(const char* ptr) | |
| { | |
| bool res = ParseLine(ptr); | |
| if (res) { | |
| if (lastState.cmd == eDril) { | |
| // split to several motions | |
| lastState.cmd = eMoveLiner; | |
| float rPlane; | |
| if (lastState.retract_mode == 99) { | |
| rPlane = lastState.r; | |
| } | |
| else { | |
| rPlane = lastState.retract_z; | |
| } | |
| float finalDepth = lastState.z; | |
| lastState.z = rPlane; | |
| Operations.push_back(lastState); | |
| lastState.z = finalDepth; | |
| Operations.push_back(lastState); | |
| lastState.z = rPlane; | |
| Operations.push_back(lastState); | |
| lastState.cmd = eDril; | |
| } | |
| else { | |
| Operations.push_back(lastState); | |
| } | |
| } | |
| return res; | |
| } | |