Extracting X Y values from a .txt file

60 views (last 30 days)
James Andrew
James Andrew on 6 Jul 2018
Commented: dpb on 9 Jul 2018
I am working on a small project using data for a 3D printer. My problem is I am having a hard time extracting the movements of the printer to a usable array. In my text file I have things like:
;TYPE:SKIRT
G1 F1500 X18.188 Y1.255 E0.36904
G1 X18.188 Y20.575 E1.33292
G1 X26.144 Y20.575 E1.72984
G1 X26.144 Y26.455 E2.02320
;TYPE:WALL-INNER
G1 F1500 X16.988 Y2.455 E9.77394
G1 X16.988 Y21.775 E10.73782
G1 X24.944 Y21.775 E11.13474
;TYPE:WALL-OUTTER
...
The code then continues with this same format for each layer. So if there are 50 layers there are 50 wall outer sections.
If all I want is each x and y numbers for all the wall outer values (while making note of which layer the xs and ys were for) how would I do that? I have been searching the net and have found nothing for something I would think would be very simple.
  6 Comments
James Andrew
James Andrew on 6 Jul 2018
Still trying to get the table to work but having just as much trouble.

Sign in to comment.

Answers (2)

Paolo
Paolo on 8 Jul 2018
Edited: Paolo on 8 Jul 2018
I think the best solution in this situation is to use regular expressions. Matlab's regexp supports named capture groups, which automatically creates a structure for you, with the names of the capture groups as fields and the captured text as data. You can read more about it here.
There are three steps in the solution below.
1. Initially the text file is parsed and each layer is extracted.
2. A loop is used to iterate over every layer to extract the types.
3. A inner loop is used to iterate over every type in every layer, and X Y data is extracted.
Here's the code:
alldata = fileread('TGC.txt');
layers = regexp(alldata,'(?:LAYER:\d)(?<layer>[\w\s.;:-]*?)(?=;LAYER:|;End)','names');
n = size(layers);
for i=1:n(2)
[layers(i).types pos] = regexp(layers(i).layer,'(?:;TYPE:)(?<TYPE>[\w-]*)','names');
pos = [pos length(layers(i).layer)];
m = size(layers(i).types);
for j=1:m(2)
layers(i).types(j).data = regexp(layers(i).layer(pos(j):pos(j+1)),'(?:G1[\w\s]*X)(? <XDATA>\d*\.\d*)(?:\sY)(?<YDATA>\d*\.\d*)','names');
end
end
The output is a structure where you can easily access your data. I am attaching screenshots to clarify what the code does.
1. There are 58 layers in your code (your index starts from 0).
2. Each of your layers has several types:
3. Each type contains X and Y data:
To access your data you can use the dot notation. If you want the X and Y data for the first layer and the first type:
layer(1).types(1).data
Note that for numerical calculations you will need to convert your data from char to double.
  3 Comments
dpb
dpb on 9 Jul 2018
I've decided I'm too old a dog for that new trick...no longer the patience needed! :)

Sign in to comment.


dpb
dpb on 6 Jul 2018
Edited: dpb on 8 Jul 2018
You'll have to parse that file to locate the desired sections...none of the builtin reading tools are able to do such a file structure on their own.
fid=fopen('TGC.txt');
while ~feof(fid) % begin a loop
l=fgetl(fid); % read a line
if contains(l,';Layer count:') % found the number layers
nLay=sscanf(l,';Layer count: %d'); % read the # layers
break % now can go counted loop
end
end
XY=cell(nLay,1); % preallocate a cell arrray that size
for i=1:nLay % go until get 'em all...
l=fgetl(fid); % read record
while ~contains(l,';TYPE:WALL-OUTER'),l=fgetl(fid);end % find the desired section
g={fgetl(fid)}; % get first record in section
while ~contains(g,';') % and build cellstr array
g=[g;{fgetl(fid)}];
end
g(end)=[]; % remove the trailing header line
g(end)=strcat(g(end),{' E'}); % normalize the row delimiters
XY{i}=str2double([extractBetween(g,"X","Y") extractBetween(g,"Y","E")]);
end
fid=fclose(fid);
ADDENDUM Above seems to work with a sorta' klunky fixup...
>> james % original name for script!!! :)
>> whos XY
Name Size Bytes Class Attributes
XY 58x1 14848 cell
>> XY{1}
ans =
17.388 2.055
17.388 21.375
25.344 21.375
25.344 25.655
3.616 25.655
3.616 21.375
11.591 21.375
11.591 2.055
12.129 2.795
>>
The layer isn't saved explicitly; it's inherent in the cell index(*); it appears for this file the size of each array is the same; not sure if that were to be a requirement, hence the cell array as opposed to, say, a 3D array by layer.
(*) Of course, it's 1-based instead of 0-based since ML arrays begin (only, unfortunately) at 1.

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!