%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% %
% dxf2coord 1.1 matrix %
% author: lukas wischounig, innsbruck, austria (dept. of geology, %
% university innsbruck), email: csad0018@uibk.ac.at %
% date: may 2005 %
% filename: dxf2coord_11_matrix.m %
% platform: matlab r14 %
% input: dxf versions r2000 - r2004 %
% output: matrices %
% output form: id x-coords y-coords z-coords %
% %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
% see !readme.m for details %
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
clear;clc;
[filename, pathname] = uigetfile({'*.dxf'},'Open File','Multiselect','off'); % choose file to open
addpath(pathname); % add path to the matlab search path
fid=fopen(filename); % open file
C=textscan(fid,'%s'); % read dxf file as cell array of strings C
fclose(fid); % close file to accelerate further computation
C=C{1,1}; % reshape array
% %%%%%%%%%%%%%%%%%%%%%%%%%% case point %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
indpoint=strcmp('AcDbPoint', C); % get line no. of points
pointnum=sum(indpoint); % get total number of lines
indpoint=find(indpoint == 1); % get line no. of lines
points=zeros(pointnum,4); % preallocate variable to increase speed
for i=1:pointnum
points(i,1)=i; % id of line
points(i,2)=str2double(C(indpoint(i)+2)); % x start
points(i,3)=str2double(C(indpoint(i)+4)); % y start
points(i,4)=str2double(C(indpoint(i)+6)); % z start
end
clear indpoint pointnum % delete garbage from workspace
%%%%%%%%%%%%%%%%%%%%%%%%%%%% end case point %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%% case line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
indline=strcmp('AcDbLine', C); % get line no. of LW polylines
linenum=sum(indline); % get total number of lines
indline=find(indline == 1); % get line no. of lines
lines=zeros(2*linenum,4); % preallocate variable to increase speed
for i=1:linenum % some funny indexing
ten=strcmp('10',C(indline(i):indline(i)+2));
ten=find(ten == 1);
lines(i+(i-1),1)=i;
lines(i+(i-1),2)=str2double(C(indline(i)+ten)); % x start
lines(i+(i-1),3)=str2double(C(indline(i)+ten+2)); % y start
lines(i+(i-1),4)=str2double(C(indline(i)+ten+4)); % z start
ten=strcmp('10',C(indline(i):indline(i)+2));
ten=find(ten == 1);
lines(i+i,1)=i;
lines(i+i,2)=str2double(C(indline(i)+ten+6)); % x end
lines(i+i,3)=str2double(C(indline(i)+ten+8)); % y end
lines(i+i,4)=str2double(C(indline(i)+ten+10)); % z end
end
clear cont indline indnum ten k linenum % delete garbage from workspace
%%%%%%%%%%%%%%%%%%%%%%%%%% end case line %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%% case polyline %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
indpoly=strcmp('AcDbPolyline', C); % get line no. of LW polylines
polynum=sum(indpoly); % get total number of polylines
indpoly=find(indpoly == 1); % get line no. of polylines
vertices=zeros(polynum,1); % detto
vertices=str2double(C(indpoly+2)); % the number of vertices is 2 lines after 'AcDbPolyline'
polylines=zeros(sum(vertices),4); % preallocate variable to increase speed, closed polys excluded
for i=1:polynum % begin coordinate extraction for every single polyline, see !readme.m or dxf reference for details and group codes
clear id xpoly ypoly zpoly % clear to avoid error
null=strcmp('0',C(indpoly(i):(indpoly(i)+(4*vertices(i)+10)))); % find next 0 after last 10...=end of entity
null=max(find(null == 1)); % max(null)=end of entity polyline(i)
ten=strcmp('10',C((indpoly(i)+4):(indpoly(i)+null))); % find 10 in C (10 is group code for x-coords)
ten=find(ten==1); % reshape ten
NUM=str2double(C(indpoly(i):(indpoly(i)+null-1))); % get subset of numeric values of entity polyline(i), strings are nan's
xpoly=NUM(ten+5);ypoly=NUM(ten+7); % x- & y- coords
threight=find(NUM(4:10)==38); % find '38' in NUM (38 is group code for z-coords)
if isempty(threight) % check out elevation
zpoly=zeros(vertices(i),1); % elevation =0
elseif threight~=0
zpoly(1:vertices(i))=NUM(threight+4);zpoly=zpoly'; % get elevation if exists
end
id(1:vertices(i))=i; % id of polyline
polyline=[id' xpoly ypoly zpoly]; % create polylinesubset
seventy=find(NUM(3:6)==70); % find 70 (70 is group code for closed polylines)
if NUM(seventy+3)==1 % if polyline is closed...
polyline(vertices(i)+1,:)=polyline(1,:); % ... add first row as last one
end
[posin(i),z]=size(polyline);
posout=cumsum(posin);
if i==1 % save subset to matrix 'polylines'
polylines(1:posin(i),:)=polyline;
else
polylines(posout(i)-posin(i)+1:posout(i),:)=polyline;
end
clear polyline % clear to avoid error
end % end case polyline
clear i id indpoly null polynum seventy ten threight vertices
clear xpoly ypoly zpoly NUM posin posout z % delete garbage
%%%%%%%%%%%%%%%%%%%%%% end case polyline %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%% case 3d polyline %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
indpoly3d=strcmp('AcDb3dPolyline', C); % get line no. of 3d polylines
poly3dnum=sum(indpoly3d); % get total number of 3d polylines
indpoly3d=find(indpoly3d == 1); % detto
vert3d=strcmp('AcDb3dPolylineVertex', C); % get line no. of vertices of 3d polylines
verttotal=sum(vert3d); % total amount of vertices
vert3d=find(vert3d == 1); % detto
poly3dlines=zeros(verttotal,4); % preallocate 3dpolys
for i=1:poly3dnum % begin coordinate extraction for every 3d polyline
if i<poly3dnum
idmax=max(find(vert3d<indpoly3d(i+1)));
else
idmax=find(vert3d==max(vert3d));
end
idmin=min(find(vert3d>indpoly3d(i)));
sub=vert3d(idmin:1:idmax); % get indices of coords
x3d=str2double(C(sub+2));
y3d=str2double(C(sub+4));
z3d=str2double(C(sub+6));
id=zeros(1,length(x3d)); % to avoid error
id(1:length(x3d))=i;
ddpoly=zeros(length(sub),4);
ddpoly=[id' x3d y3d z3d];
seventy=strcmp('70',C(indpoly3d+6:indpoly3d+11)); % find out if polyline is closed
seventy=find(seventy==1);
closed=str2double(C(indpoly3d(i)+seventy+6)); % get value of '70'+1 line
closed=dec2bin(closed,8);closed=closed(:);closed=closed(8); % because group code '70' is binary coded
if closed=='1' % if polyline is closed
[x,y]=size(ddpoly);
ddpoly(x+1,:)=ddpoly(1,:); % ... add first row as last one
end
[posin(i),z]=size(ddpoly); % find out positions to save
posout=cumsum(posin);
if i==1 % save subset to matrix 'polylines'
poly3dlines(1:posin(i),:)=ddpoly;
else
poly3dlines(posout(i)-posin(i)+1:posout(i),:)=ddpoly;
end
end
clear closed ddpoly i id idmax idmin indpoly3d poly3dnum x3d y3d z3d
clear posin posout seventy sub vert3d verttotal x y z % delete garbage
%%%%%%%%%%%%%%%%%%%%%%%%%% end case 3d polyline %%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%% case 3d faces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
face3d=strcmp('AcDbFace', C); % get line no. of 3d faces
face3dnum=sum(face3d); % get total number of 3d faces
face3d=find(face3d == 1); % detto
faces3d=zeros(4*face3dnum+1,4); % preallocate, +1 to enable resizing at the end
for i=1:face3dnum
fac3d=zeros(4,4);
fac3d(1,1)=i; % again(id,x-coord,y-coord,z_coords)
fac3d(1,2)=str2double(C(face3d(i)+2));
fac3d(1,3)=str2double(C(face3d(i)+4));
fac3d(1,4)=str2double(C(face3d(i)+6));
fac3d(2,1)=i;
fac3d(2,2)=str2double(C(face3d(i)+8));
fac3d(2,3)=str2double(C(face3d(i)+10));
fac3d(2,4)=str2double(C(face3d(i)+12));
fac3d(3,1)=i;
fac3d(3,2)=str2double(C(face3d(i)+14));
fac3d(3,3)=str2double(C(face3d(i)+16));
fac3d(3,4)=str2double(C(face3d(i)+18));
fac3d(4,1)=i;
fac3d(4,2)=str2double(C(face3d(i)+20));
fac3d(4,3)=str2double(C(face3d(i)+22));
fac3d(4,4)=str2double(C(face3d(i)+24));
if fac3d(4,2)==fac3d(3,2) % find out if 4th coord pair == 3rd
fac3d=fac3d(1:3,:); % if so, delete 4th coord pair
end
[posin(i),z]=size(fac3d); % find out positions to save
posout=cumsum(posin);
if i==1 % save subset to matrix 'polylines'
faces3d(1:posin(i),:)=fac3d;
else
faces3d(posout(i)-posin(i)+1:posout(i),:)=fac3d;
end
end
faces3d=faces3d(1:min(find(faces3d(:,1)==0))-1,:); % resize face3dmatrix
clear posin posout face3d face3dnum fac3d i z % finished so far
%%%%%%%%%%%%%%%%%%%%%%%%%% end case 3d faces %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%%%%%%%%%%%%%%%%%%%%%%%%%%% case circles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
%get some markers and help variables
cir=strcmp('AcDbCircle', C); % get line no. of 3d faces
cirnum=sum(cir); % get total number of 3d faces
cir=find(cir == 1); % detto
circles=zeros(cirnum,5); % preallocate (id x y z radius)
for i=1:cirnum
circ=zeros(1,5);
threenine=strcmp('39',(C(cir(i):cir(i)+1))); % '39' is the group code of entity thickness
threenine=find(threenine==1);
if isempty (threenine) % get coordinates and radii
circ=zeros(1,5);
circ(1,1)=i;
circ(1,2)=str2double(C(cir(i)+2)); % x-coord of center
circ(1,3)=str2double(C(cir(i)+4)); % y-coord of center
circ(1,4)=str2double(C(cir(i)+6)); % z-coord of center
circ(1,5)=str2double(C(cir(i)+8)); % radius of circle
else
circ=zeros(1,5);
circ(1,1)=i;
circ(1,2)=str2double(C(cir(i)+4)); % x-coord of center
circ(1,3)=str2double(C(cir(i)+6)); % y-coord of center
circ(1,4)=str2double(C(cir(i)+8)); % z-coord of center
circ(1,5)=str2double(C(cir(i)+10)); % radius of circle
end
circles(i,:)=circ; % save to matrix
end
clear threenine i cirnum circ cir % delete garbage
%%%%%%%%%%%%%%%%%%%%%%%%%%% end case circles %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
rmpath(pathname); % remove path from the matlab search path