mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-27 20:13:50 +02:00
237 lines
5.6 KiB
ObjectPascal
237 lines
5.6 KiB
ObjectPascal
{
|
|
Reads AvisoCNC G-Code
|
|
|
|
License: The same modified LGPL as the Free Pascal RTL
|
|
See the file COPYING.modifiedLGPL for more details
|
|
|
|
AUTHORS: Felipe Monteiro de Carvalho
|
|
Pedro Sol Pegorini L de Lima
|
|
}
|
|
unit avisocncgcodereader;
|
|
|
|
{$mode objfpc}{$H+}
|
|
|
|
interface
|
|
|
|
uses
|
|
Classes, SysUtils,
|
|
fpvectorial;
|
|
|
|
type
|
|
|
|
{ Used by tcutils.SeparateString }
|
|
T10Strings = array[0..9] of shortstring;
|
|
|
|
{ TvAvisoCNCGCodeReader }
|
|
|
|
TvAvisoCNCGCodeReader = class(TvCustomVectorialReader)
|
|
private
|
|
LastX, LastY, LastZ: Double;
|
|
function SeparateString(AString: string; ASeparator: Char): T10Strings;
|
|
procedure ReadString(AStr: string; AData: TvVectorialPage);
|
|
function GetCoordinate(AStr: shortstring): Integer;
|
|
function GetCoordinateValue(AStr: shortstring): Double;
|
|
public
|
|
{ General reading methods }
|
|
procedure ReadFromStrings(AStrings: TStrings; AData: TvVectorialDocument); override;
|
|
end;
|
|
|
|
implementation
|
|
|
|
const
|
|
{ Coordinate constants }
|
|
|
|
INT_COORDINATE_NONE = 0;
|
|
INT_COORDINATE_X = 1;
|
|
INT_COORDINATE_Y = 2;
|
|
INT_COORDINATE_Z = 3;
|
|
|
|
{ GCode constants }
|
|
|
|
STR_GCODE_LINEAR_MOVE = 'G01';
|
|
STR_GCODE_STEPPER_MOVE = 'S01';
|
|
STR_GCODE_2DBEZIER_MOVE = 'B02';
|
|
STR_GCODE_3DBEZIER_MOVE = 'B03';
|
|
STR_GCODE_DRILL_UP = 'P01';
|
|
STR_GCODE_DRILL_DOWN = 'P02';
|
|
|
|
{ TvAvisoCNCGCodeReader }
|
|
|
|
{@@
|
|
Reads a string and separates it in substring
|
|
using ASeparator to delimite them.
|
|
|
|
Limits:
|
|
|
|
Number of substrings: 10 (indexed 0 to 9)
|
|
Length of each substring: 255 (they are shortstrings)
|
|
}
|
|
function TvAvisoCNCGCodeReader.SeparateString(AString: string; ASeparator: Char): T10Strings;
|
|
var
|
|
i, CurrentPart: Integer;
|
|
begin
|
|
CurrentPart := 0;
|
|
|
|
{ Clears the result }
|
|
for i := 0 to 9 do Result[i] := '';
|
|
|
|
{ Iterates througth the string, filling strings }
|
|
for i := 1 to Length(AString) do
|
|
begin
|
|
if Copy(AString, i, 1) = ASeparator then
|
|
begin
|
|
Inc(CurrentPart);
|
|
|
|
{ Verifies if the string capacity wasn't exceeded }
|
|
if CurrentPart > 9 then Exit;
|
|
end
|
|
else
|
|
Result[CurrentPart] := Result[CurrentPart] + Copy(AString, i, 1);
|
|
end;
|
|
end;
|
|
|
|
procedure TvAvisoCNCGCodeReader.ReadString(AStr: string;
|
|
AData: TvVectorialPage);
|
|
var
|
|
AParams: T10Strings;
|
|
DestX, DestY, DestZ: Double;
|
|
i: Integer;
|
|
begin
|
|
{$ifdef FPVECTORIALDEBUG}
|
|
WriteLn('TvAvisoCNCGCodeReader.ReadString ', AStr);
|
|
{$endif}
|
|
AParams := SeparateString(AStr, ' ');
|
|
|
|
{
|
|
Format may be:
|
|
G01 X3
|
|
G01 X3 Y4
|
|
G01 X3 Y4 Z2
|
|
}
|
|
if AParams[0] = STR_GCODE_DRILL_UP then
|
|
begin
|
|
AData.AddLineToPath(LastX, LastY, 0);
|
|
LastZ := 0;
|
|
end
|
|
else if AParams[0] = STR_GCODE_DRILL_DOWN then
|
|
begin
|
|
AData.AddLineToPath(LastX, LastY, 50);
|
|
LastZ := 50;
|
|
end
|
|
else if AParams[0] = STR_GCODE_LINEAR_MOVE then
|
|
begin
|
|
DestX := LastX;
|
|
DestY := LastY;
|
|
DestZ := LastZ;
|
|
|
|
for i := 1 to 3 do
|
|
begin
|
|
case GetCoordinate(AParams[i]) of
|
|
INT_COORDINATE_X: DestX := GetCoordinateValue(AParams[i]);
|
|
INT_COORDINATE_Y: DestY := GetCoordinateValue(AParams[i]);
|
|
INT_COORDINATE_Z: DestZ := GetCoordinateValue(AParams[i]);
|
|
else
|
|
// error
|
|
end;
|
|
end;
|
|
|
|
AData.AddLineToPath(DestX, DestY, DestZ);
|
|
|
|
LastX := DestX;
|
|
LastY := DestY;
|
|
LastZ := DestZ;
|
|
end
|
|
else if AParams[0] = STR_GCODE_2DBEZIER_MOVE then
|
|
begin
|
|
AData.AddBezierToPath(
|
|
GetCoordinateValue(AParams[1]),
|
|
GetCoordinateValue(AParams[2]),
|
|
GetCoordinateValue(AParams[3]),
|
|
GetCoordinateValue(AParams[4]),
|
|
GetCoordinateValue(AParams[5]),
|
|
GetCoordinateValue(AParams[6])
|
|
);
|
|
|
|
LastX := GetCoordinateValue(AParams[5]);
|
|
LastY := GetCoordinateValue(AParams[6]);
|
|
end
|
|
else if AParams[0] = STR_GCODE_3DBEZIER_MOVE then
|
|
begin
|
|
AData.AddBezierToPath(
|
|
GetCoordinateValue(AParams[1]),
|
|
GetCoordinateValue(AParams[2]),
|
|
GetCoordinateValue(AParams[3]),
|
|
GetCoordinateValue(AParams[4]),
|
|
GetCoordinateValue(AParams[5]),
|
|
GetCoordinateValue(AParams[6]),
|
|
GetCoordinateValue(AParams[7]),
|
|
GetCoordinateValue(AParams[8]),
|
|
GetCoordinateValue(AParams[9])
|
|
);
|
|
|
|
LastX := GetCoordinateValue(AParams[7]);
|
|
LastY := GetCoordinateValue(AParams[8]);
|
|
LastZ := GetCoordinateValue(AParams[9]);
|
|
end;
|
|
{else
|
|
begin
|
|
Ignore any of these codes:
|
|
|
|
STR_GCODE_STEPPER_MOVE
|
|
|
|
and anything else
|
|
end;}
|
|
end;
|
|
|
|
function TvAvisoCNCGCodeReader.GetCoordinate(AStr: shortstring): Integer;
|
|
begin
|
|
Result := INT_COORDINATE_NONE;
|
|
|
|
if AStr = '' then Exit
|
|
else if AStr[1] = 'X' then Result := INT_COORDINATE_X
|
|
else if AStr[1] = 'Y' then Result := INT_COORDINATE_Y
|
|
else if AStr[1] = 'Z' then Result := INT_COORDINATE_Z;
|
|
end;
|
|
|
|
function TvAvisoCNCGCodeReader.GetCoordinateValue(AStr: shortstring): Double;
|
|
begin
|
|
Result := 0.0;
|
|
|
|
if Length(AStr) <= 1 then Exit;
|
|
|
|
Result := StrToFloat(Copy(AStr, 2, Length(AStr) - 1));
|
|
end;
|
|
|
|
{@@
|
|
The information of each separate path is lost in G-Code files
|
|
Only one path uniting all of them is created when reading G-Code
|
|
}
|
|
procedure TvAvisoCNCGCodeReader.ReadFromStrings(AStrings: TStrings;
|
|
AData: TvVectorialDocument);
|
|
var
|
|
i: Integer;
|
|
FirstPage: TvVectorialPage;
|
|
begin
|
|
{$ifdef FPVECTORIALDEBUG}
|
|
WriteLn('TvAvisoCNCGCodeReader.ReadFromStrings AStrings = ', PtrInt(AStrings), ' AData = ', PtrInt(AData));
|
|
{$endif}
|
|
|
|
FirstPage := AData.AddPage();
|
|
FirstPage.StartPath(0, 0);
|
|
|
|
for i := 0 to AStrings.Count - 1 do
|
|
ReadString(AStrings.Strings[i], FirstPage);
|
|
|
|
{$ifdef FPVECTORIALDEBUG}
|
|
WriteLn('AData.EndPath');
|
|
{$endif}
|
|
FirstPage.EndPath();
|
|
end;
|
|
|
|
initialization
|
|
|
|
RegisterVectorialReader(TvAvisoCNCGCodeReader, vfGCodeAvisoCNCPrototipoV5);
|
|
|
|
end.
|
|
|