| | function mvtk_write(M,filename,format) |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | |
| |
|
| |
|
| | |
| | |
| | if nargin < 2 || isempty(filename), filename = 'untitled'; end |
| | if nargin < 3 || isempty(format) |
| | [pth,name,ext] = fileparts(filename); |
| | switch ext |
| | case {'','.vtk'} |
| | ext = '.vtk'; |
| | format = 'legacy-ascii'; |
| | case 'vtp' |
| | format = 'xml-ascii'; |
| | case {'.vti','.vtr','.vts','.vtu'} |
| | format = 'xml-ascii'; |
| | warning('Only partially handled.'); |
| | otherwise |
| | error('Unknown file extension.'); |
| | end |
| | else |
| | switch lower(format) |
| | case {'legacy','legacy-ascii','legacy-binary'} |
| | ext = '.vtk'; |
| | case {'xml','xml-ascii','xml-binary','xml-appended'} |
| | ext = '.vtp'; |
| | otherwise |
| | error('Unknown file format.'); |
| | end |
| | end |
| |
|
| | |
| | |
| | [pth,name,e] = fileparts(filename); |
| | if ~strcmpi(e,ext) |
| | warning('Changing file extension from %s to %s.',e,ext); |
| | end |
| | filename = fullfile(pth,[name ext]); |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | |
| | |
| | |
| |
|
| | |
| | if ~isfield(M,'normals') |
| | M.normals = compute_normals(M); |
| | end |
| |
|
| | |
| | |
| | switch lower(format) |
| | case {'legacy','legacy-ascii'} |
| | mvtk_write_legacy(M,filename,'ASCII'); |
| | case {'legacy-binary'} |
| | mvtk_write_legacy(M,filename,'BINARY'); |
| | case {'xml','xml-ascii'} |
| | mvtk_write_xml(M,filename,'ASCII'); |
| | case {'xml-binary'} |
| | mvtk_write_xml(M,filename,'BINARY'); |
| | case {'xml-appended'} |
| | mvtk_write_xml(M,filename,'APPENDED'); |
| | otherwise |
| | error('Unknown file format.'); |
| | end |
| |
|
| |
|
| | |
| | |
| | |
| | function fid = mvtk_write_legacy(s,filename,format) |
| |
|
| | |
| | |
| | if nargin == 2, format = 'ASCII'; else format = upper(format); end |
| | switch format |
| | case 'ASCII' |
| | fopen_opts = {'wt'}; |
| | write_data = @(fid,fmt,prec,dat) fprintf(fid,fmt,dat); |
| | case 'BINARY' |
| | fopen_opts = {'wb','ieee-be'}; |
| | write_data = @(fid,fmt,prec,dat) [fwrite(fid,dat,prec);fprintf(fid,'\n');]; |
| | otherwise |
| | error('Unknown file format.'); |
| | end |
| | fid = fopen(filename,fopen_opts{:}); |
| | if fid == -1 |
| | error('Unable to write file %s: permission denied.',filename); |
| | end |
| |
|
| | |
| | |
| |
|
| | |
| | |
| | fprintf(fid,'# vtk DataFile Version 2.0\n'); |
| |
|
| | |
| | |
| | hdr = 'Saved using mVTK'; |
| | fprintf(fid,'%s\n',hdr(1:min(length(hdr),256))); |
| |
|
| | |
| | |
| | fprintf(fid,'%s\n',format); |
| |
|
| | |
| | |
| | |
| | |
| | if isfield(s,'vertices') || isfield(s,'faces') |
| | type = 'POLYDATA'; |
| | elseif isfield(s,'spacing') |
| | type = 'STRUCTURED_POINTS'; |
| | |
| | |
| | else |
| | error('Unknown dataset structure.'); |
| | end |
| | fprintf(fid,'DATASET %s\n',type); |
| | if isfield(s,'vertices') |
| | fprintf(fid,'POINTS %d %s\n',size(s.vertices,1),'float'); |
| | write_data(fid,'%f %f %f\n','float32',s.vertices'); |
| | end |
| | if isfield(s,'faces') |
| | nFaces = size(s.faces,1); |
| | nConn = size(s.faces,2); |
| | fprintf(fid,'POLYGONS |
| | dat = uint32([repmat(nConn,1,nFaces); (s.faces'-1)]); |
| | fmt = repmat(' |
| | write_data(fid,[fmt '\n'],'uint32',dat); |
| | end |
| | if isfield(s,'spacing') |
| | fprintf(fid,'DIMENSIONS %d %d %d\n',size(s.cdata)); |
| | fprintf(fid,'ORIGIN %f %f %f\n',s.origin); |
| | fprintf(fid,'SPACING %f %f %f\n',s.spacing); |
| | s.cdata = s.cdata(:); |
| | end |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | |
| | fprintf(fid,'\n'); |
| |
|
| | |
| | |
| | point_data_hdr = false; |
| |
|
| | |
| | if isfield(s,'cdata') && ~isempty(s.cdata) |
| | if ~point_data_hdr |
| | fprintf(fid,'POINT_DATA %d\n',size(s.cdata,1)); |
| | point_data_hdr = true; |
| | end |
| | if ~isfield(s,'lut') |
| | lut_name = 'default'; |
| | else |
| | lut_name = 'my_lut'; |
| | if size(s.lut,2) == 3 |
| | s.lut = [s.lut ones(size(s.lut,1),1)]; |
| | end |
| | end |
| | dataName = 'cdata'; |
| | fprintf(fid,'SCALARS %s %s %d\n',dataName,'float',size(s.cdata,2)); |
| | fprintf(fid,'LOOKUP_TABLE %s\n',lut_name); |
| | fmt = repmat('%f ',1,size(s.cdata,2)); fmt(end) = ''; |
| | write_data(fid,[fmt '\n'],'float32',s.cdata'); |
| | if ~strcmp(lut_name,'default') |
| | fprintf(fid,'LOOKUP_TABLE |
| | if strcmp(format,'ASCII') |
| | |
| | write_data(fid,'%f %f %f %f\n','float32',s.lut'); % rescale |
| | else |
| | % four unsigned char values per table entry |
| | write_data(fid,'','uint8',uint8(s.lut')); |
| | end |
| | end |
| | end |
| |
|
| | |
| | if isfield(s,'color') && ~isempty(s.color) |
| | if ~point_data_hdr |
| | fprintf(fid,'POINT_DATA %d\n',size(s.color,1)); |
| | point_data_hdr = true; |
| | end |
| | dataName = 'color'; |
| | fprintf(fid,'COLOR_SCALARS %s %d\n',dataName,size(s.color,2)); |
| | if strcmp(format,'ASCII') |
| | |
| | fmt = repmat('%f ',1,size(s.color,2)); fmt(end) = ''; |
| | write_data(fid,[fmt '\n'],'float32',s.color'); % rescale |
| | else |
| | % nValues unsigned char values per scalar value |
| | write_data(fid,'','uint8',uint8(s.color')); |
| | end |
| | end |
| |
|
| | |
| | if isfield(s,'vectors') && ~isempty(s.vectors) |
| | if ~point_data_hdr |
| | fprintf(fid,'POINT_DATA %d\n',size(s.vectors,1)); |
| | point_data_hdr = true; |
| | end |
| | dataName = 'vectors'; |
| | fprintf(fid,'VECTORS %s %s\n',dataName,'float'); |
| | write_data(fid,'%f %f %f\n','float32',s.vectors'); |
| | end |
| | |
| | %-NORMALS |
| | if isfield(s,'normals') && ~isempty(s.normals) |
| | if ~point_data_hdr |
| | fprintf(fid,'POINT_DATA |
| | point_data_hdr = true; |
| | end |
| | dataName = 'normals'; |
| | fprintf(fid,'NORMALS %s %s\n',dataName,'float'); |
| | write_data(fid,'%f %f %f\n','float32',-s.normals'); |
| | end |
| | |
| | %-TENSORS |
| | if isfield(s,'tensors') && ~isempty(s.tensors) |
| | if ~point_data_hdr |
| | fprintf(fid,'POINT_DATA |
| | point_data_hdr = true; |
| | end |
| | dataName = 'tensors'; |
| | fprintf(fid,'TENSORS %s %s\n',dataName,'float'); |
| | write_data(fid,repmat('%f %f %f\n',1,3),'float32',s.tensors'); |
| | end |
| | |
| | %-Close file |
| | %-------------------------------------------------------------------------- |
| | fclose(fid); |
| | |
| | |
| | %========================================================================== |
| | % function fid = mvtk_write_xml(s,filename,format) |
| | %========================================================================== |
| | function fid = mvtk_write_xml(s,filename,format) |
| | |
| | %-Open file |
| | %-------------------------------------------------------------------------- |
| | if nargin == 2, format = 'ascii'; else format = lower(format); end |
| | clear store_appended_data |
| | switch format |
| | case 'ascii' |
| | fopen_opts = {'wt'}; |
| | write_data = @(fmt,dat) deal(NaN,sprintf(fmt,dat)); |
| | case 'binary' |
| | fopen_opts = {'wb','ieee-le'}; |
| | write_data = @(fmt,dat) deal(NaN,[... |
| | base64encode(typecast(uint32(numel(dat)*numel(typecast(dat(1),'uint8'))),'uint8')) ... |
| | base64encode(typecast(dat(:),'uint8'))]); |
| | case 'appended' |
| | fopen_opts = {'wt'}; |
| | store_appended_data('start'); |
| | store_appended_data('base64'); % format: raw, [base64] |
| | store_appended_data('none'); % compression: none, [zlib] |
| | write_data = @(fmt,dat) deal(store_appended_data(fmt,dat),''); |
| | otherwise |
| | error('Unknown format.'); |
| | end |
| | fid = fopen(filename,fopen_opts{:}); |
| | if fid == -1 |
| | error('Unable to write file |
| | end |
| |
|
| | |
| | |
| | o = @(x) blanks(x*3); |
| |
|
| | |
| | |
| | fprintf(fid,'<?xml version="1.0"?>\n'); |
| |
|
| | |
| | |
| | VTKFile = struct; |
| | VTKFile.type = 'PolyData'; |
| | VTKFile.version = '0.1'; |
| | VTKFile.byte_order = 'LittleEndian'; |
| | VTKFile.header_type = 'UInt32'; |
| | if strcmp(store_appended_data('compression'),'zlib') |
| | VTKFile.compressor = 'vtkZLibDataCompressor'; |
| | end |
| | fprintf(fid,'<VTKFile'); |
| | for i=fieldnames(VTKFile)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>\n'); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<PolyData>\n',o(1)); |
| | Piece = struct; |
| | Piece.NumberOfPoints = sprintf('%d',size(s.vertices,1)); |
| | Piece.NumberOfVerts = sprintf('%d',0); |
| | Piece.NumberOfLines = sprintf('%d',0); |
| | Piece.NumberOfStrips = sprintf('%d',0); |
| | Piece.NumberOfPolys = sprintf('%d',size(s.faces,1)); |
| | fprintf(fid,'%s<Piece',o(2)); |
| | for i=fieldnames(Piece)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>\n'); |
| |
|
| | |
| | |
| | PointData = struct; |
| | if isfield(s,'cdata') && ~isempty(s.cdata) |
| | PointData.Scalars = 'scalars'; |
| | end |
| | if isfield(s,'normals') && ~isempty(s.normals) |
| | PointData.Normals = 'normals'; |
| | end |
| | fprintf(fid,'%s<PointData',o(3)); |
| | for i=fieldnames(PointData)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>\n'); |
| |
|
| | |
| | if isfield(s,'cdata') && ~isempty(s.cdata) |
| | [offset,dat] = write_data('%f ',single(s.cdata')); |
| | DataArray = struct; |
| | DataArray.type = 'Float32'; |
| | DataArray.Name = 'scalars'; |
| | DataArray.NumberOfComponents = sprintf(' |
| | DataArray.format = format; |
| | if ~isnan(offset), DataArray.offset = sprintf('%d',offset); end |
| | fprintf(fid,'%s<DataArray',o(4)); |
| | for i=fieldnames(DataArray)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>%s</DataArray>\n',dat); |
| | end |
| |
|
| | |
| | if isfield(s,'normals') && ~isempty(s.normals) |
| | [offset,dat] = write_data('%f ',single(-s.normals')); |
| | DataArray = struct; |
| | DataArray.type = 'Float32'; |
| | DataArray.Name = 'normals'; |
| | DataArray.NumberOfComponents = sprintf(' |
| | DataArray.format = format; |
| | if ~isnan(offset), DataArray.offset = sprintf('%d',offset); end |
| | fprintf(fid,'%s<DataArray',o(4)); |
| | for i=fieldnames(DataArray)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>%s</DataArray>\n',dat); |
| | end |
| |
|
| | fprintf(fid,'%s</PointData>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<CellData/>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<Points>\n',o(3)); |
| | if isfield(s,'vertices') |
| | [offset,dat] = write_data('%f ',single(s.vertices')); |
| | DataArray = struct; |
| | DataArray.type = 'Float32'; |
| | DataArray.Name = 'Vertices'; |
| | DataArray.NumberOfComponents = sprintf(' |
| | DataArray.format = format; |
| | if ~isnan(offset), DataArray.offset = sprintf('%d',offset); end |
| | fprintf(fid,'%s<DataArray',o(4)); |
| | for i=fieldnames(DataArray)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>%s</DataArray>\n',dat); |
| | end |
| | fprintf(fid,'%s</Points>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<Verts/>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<Lines/>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<Strips/>\n',o(3)); |
| |
|
| | |
| | |
| | fprintf(fid,'%s<Polys>\n',o(3)); |
| | if isfield(s,'faces') |
| | [offset,dat] = write_data('%d ',uint32(s.faces'-1)); |
| | DataArray = struct; |
| | DataArray.type = 'UInt32'; |
| | DataArray.Name = 'connectivity'; |
| | DataArray.format = format; |
| | if ~isnan(offset), DataArray.offset = sprintf(' |
| | fprintf(fid,'%s<DataArray',o(4)); |
| | for i=fieldnames(DataArray)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>%s</DataArray>\n',dat); |
| | |
| | [offset,dat] = write_data('%d ',uint32(3:3:3*size(s.faces,1))); |
| | DataArray = struct; |
| | DataArray.type = 'UInt32'; |
| | DataArray.Name = 'offsets'; |
| | DataArray.format = format; |
| | if ~isnan(offset), DataArray.offset = sprintf('%d',offset); end |
| | fprintf(fid,'%s<DataArray',o(4)); |
| | for i=fieldnames(DataArray)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>%s</DataArray>\n',dat); |
| | end |
| | fprintf(fid,'%s</Polys>\n',o(3)); |
| |
|
| | fprintf(fid,'%s</Piece>\n',o(2)); |
| | fprintf(fid,'%s</PolyData>\n',o(1)); |
| |
|
| | |
| | |
| | if strcmp(format,'appended') |
| | dat = store_appended_data('retrieve'); |
| | store_appended_data('stop'); |
| | AppendedData = struct; |
| | AppendedData.encoding = store_appended_data('encoding'); |
| | fprintf(fid,'%s<AppendedData',o(1)); |
| | for i=fieldnames(AppendedData)' |
| | fprintf(fid,' |
| | end |
| | fprintf(fid,'>\n%s_',o(2)); |
| | fwrite(fid,dat); |
| | fprintf(fid,'\n%s</AppendedData>\n',o(1)); |
| | end |
| |
|
| | fprintf(fid,'</VTKFile>\n'); |
| |
|
| | |
| | |
| | fclose(fid); |
| |
|
| |
|
| | |
| | |
| | |
| | function varargout = store_appended_data(fmt,dat) |
| |
|
| | persistent fid encoding compression |
| |
|
| | if isempty(encoding), encoding = 'raw'; end |
| | if isempty(compression), compression = 'none'; end |
| | if ~nargin, fmt = 'start'; end |
| | if nargin < 2 |
| | varargout = {}; |
| | switch lower(fmt) |
| | case 'start' |
| | filename = tempname; |
| | fid = fopen(filename,'w+b'); |
| | if fid == -1 |
| | error('Cannot open temporary file.'); |
| | end |
| | case 'stop' |
| | filename = fopen(fid); |
| | fclose(fid); |
| | delete(filename); |
| | fid = -1; |
| | case 'retrieve' |
| | frewind(fid); |
| | varargout = {fread(fid)}; |
| | case 'encoding' |
| | varargout = {encoding}; |
| | case 'compression' |
| | varargout = {compression}; |
| | case {'raw','base64'} |
| | encoding = fmt; |
| | case {'none','zlib'} |
| | compression = fmt; |
| | otherwise |
| | error('Unknown action.'); |
| | end |
| | return; |
| | end |
| |
|
| | varargout = {ftell(fid)}; |
| | N = uint32(numel(dat)*numel(typecast(dat(1),'uint8'))); |
| | switch encoding |
| | case 'raw' |
| | switch compression |
| | case 'none' |
| | dat = typecast(dat(:),'uint8'); |
| | hdr = N; |
| | case 'zlib' |
| | dat = zstream('C',typecast(dat(:),'uint8')); |
| | hdr = uint32([1 N N numel(dat)]); |
| | otherwise |
| | error('Unknown compression.'); |
| | end |
| | fwrite(fid,hdr,'uint32'); |
| | fwrite(fid,dat,class(dat)); |
| | case 'base64' |
| | switch compression |
| | case 'none' |
| | dat = typecast(dat(:),'uint8'); |
| | hdr = N; |
| | case 'zlib' |
| | dat = zstream('C',typecast(dat(:),'uint8')); |
| | hdr = uint32([1 N N numel(dat)]); |
| | otherwise |
| | error('Unknown compression.'); |
| | end |
| | fwrite(fid,base64encode(typecast(hdr,'uint8'))); |
| | fwrite(fid,base64encode(dat)); |
| | otherwise |
| | error('Unknown encoding.'); |
| | end |
| |
|
| |
|
| | |
| | |
| | |
| | function N = compute_normals(S) |
| | try |
| | t = triangulation(double(S.faces),double(S.vertices)); |
| | N = -double(t.vertexNormal); |
| | normN = sqrt(sum(N.^2,2)); |
| | normN(normN < eps) = 1; |
| | N = N ./ repmat(normN,1,3); |
| | catch |
| | N = []; |
| | end |
| |
|