function [vert, tria]=read3ds(filename,glue,show)
%READ3DS(filename,<glue>,<show>) read 3ds-file
%input:	filename, optional: flag 'glue', optional: flag 'show'
%output:	[vert, tria]: cellarray vertices, cellarray triangles
%different cells contain different parts of the object.
%   vertices: each cell contains an n x 3 - matrix v, defining
%             vertex-coordinates: v = ([x1 y1 z1];...;[xn yn zn])
%   triangles:each cell contains an m x 3 - matrix t, defining
%             the indices of the triangle's vertices in the corresponding
%             vertex-cell. index-count starts on 1.
%if flag 'glue' is 1, the cells are concatenated, i.e. all vertices are
%collected in vert{1}, all triangles are collected in tria{1}


vert={};
tria={};

f=fopen(filename,'r');
if f == -1
   fprintf('ERROR: read3ds: could not open file %s.\n',filename);
   return;   
end


%check file-format
main3ds=hex2dec('4d4d');
edit3ds=hex2dec('3d3d');
editobject=hex2dec('4000');
objtrimesh=hex2dec('4100');
vertices=hex2dec('4110'); 
triangles=hex2dec('4120');


pos_trimesh=0;
pos_vertices=0;
pos_triangles=0;


% read vertices -------------------------------------
cellindex=1;
ok=lookforchunk(f,main3ds);
if ok
   ok=lookforchunk(f,edit3ds);
end
if ok
   while 1
   	offset=lookforchunk(f,editobject);	%4000
      
      if (offset ==0)
         break
      end   
      
      %4000 found, look for 4100
      pos=ftell(f);
      readname(f);
      ok=lookforchunk(f,objtrimesh);	%4100
      if ok
      	ok=lookforchunk(f,vertices);	%4110
         if ok
            number=readshort(f);
            dummy=fread(f,number*3,'float32');
            v=zeros(3,number);
            for i=1:number
               start=1+(i-1)*3;
               v(1:3,i)=dummy(start:start+2);
            end
            vert{cellindex}=v';
            cellindex=cellindex+1;
         end
      end         
         
      %step through all x4000 chunks
      fseek(f,pos+offset-6,'bof');   
   end
end



% read triangles -------------------------------------
fseek(f,0,'bof');
cellindex=1;
ok=lookforchunk(f,main3ds);
if ok
   ok=lookforchunk(f,edit3ds);
end
if ok
   while 1
   	offset=lookforchunk(f,editobject);	%4000
      
      if (offset ==0)
         break
      end   
      
      %4000 found, look for 4100
      pos=ftell(f);
      readname(f);
      ok=lookforchunk(f,objtrimesh);	%4100
      if ok
      	ok=lookforchunk(f,triangles);	%4120
         if ok
            number=readshort(f);
            dummy=fread(f,number*4,'uint16');
            t=zeros(3,number);
            for i=1:number
               start=1+(i-1)*4;
               t(1:3,i)=dummy(start:start+2);
            end
            tria{cellindex}=t' + 1;	%startindex of vertices: 1
            cellindex=cellindex+1;
         end
      end         
         
      %step through all x4000 chunks
      fseek(f,pos+offset-6,'bof');   
   end
end
fclose(f);

% ------------------------------------------------
% glue parts ?
if exist('glue') & (glue == 1)
   number=length(vert);
   for i=1:number
      b(i)=length(vert{i});
   end
   b=cumsum(b);
   
   %add offsets to vertex-indices in triangle-cells
   for i=2:number
      tria{i}=tria{i}+b(i-1);
   end
   
   %glue !
   v=[];
   t=[];
   for i=1:number
      v=[v;vert{i}];
      t=[t;tria{i}];
   end
   vert={};
   tria={};
   vert{1}=v;
   tria{1}=t;
end

% show -----------------
if exist('show') & show==1
   plot3ds(vert,tria,0,'flat');
end

% bye.
return


%-----------------------------------------------------------
%local functions
%readshort
function s=readshort(f)
s=fread(f,1)+256*fread(f,1);
return

%readlong
function l=readlong(f)
l=readshort(f);
l1=readshort(f);
l=l+65536*l1;
return

%lookforchunk
function offset=lookforchunk(f,id)
while 1
   chunk=readshort(f);
   if feof(f)
      offset=0;
      break
   end
  
   ok=(chunk==id);
   if (ok)
      offset=readlong(f);
      break;
   end
   offset=readlong(f);
   fseek(f,offset-6,0);
end
return

%readname
function readname(f)
while fread(f,1)
end
return

