0001 function ply_write ( Elements, Path, Format, Str )
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036
0037
0038
0039
0040
0041
0042
0043
0044
0045
0046
0047
0048
0049
0050
0051
0052
0053
0054
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066 if ( nargin < 4 )
0067
0068 Str = '';
0069
0070 if ( nargin < 3 )
0071 Format = 'binary_big_endian';
0072 elseif strcmpi(Format,'double')
0073 Str = 'double';
0074 Format = 'binary_big_endian';
0075 end
0076
0077 end
0078
0079 [ fid, Msg ] = fopen ( Path, 'wt' );
0080
0081 if ( fid == -1 )
0082 error(Msg);
0083 end
0084
0085 PlyTypeNames = {'char','uchar','short','ushort','int','uint','float','double', ...
0086 'char8','uchar8','short16','ushort16','int32','uint32','float32','double64'};
0087 FWriteTypeNames = {'schar','uchar','int16','uint16','int32','uint32','single','double'};
0088 MatlabTypeNames = {'int8','uint8','int16','uint16','int32','uint32','single','double'};
0089 PrintfTypeChar = {'%d','%u','%d','%u','%d','%u','%-.6f','%-.14e'};
0090 IntegerDataMin = [-128,0,-2^15,-2^31,0];
0091 IntegerDataMax = [127,255,2^16-1,2^31-1,2^32-1];
0092
0093
0094
0095 fprintf(fid,'ply\nformat %s 1.0\ncomment created by MATLAB ply_write\n',Format);
0096 ElementNames = fieldnames(Elements);
0097 NumElements = length(ElementNames);
0098 Data = cell(NumElements,1);
0099
0100 for i = 1 : NumElements
0101
0102 eval(['tmp=isa(Elements.',ElementNames{i},',''struct'');']);
0103
0104 if ( tmp )
0105 eval(['PropertyNames{i}=fieldnames(Elements.',ElementNames{i},');']);
0106 else
0107 PropertyNames{i} = [];
0108 end
0109
0110 if ( ~isempty(PropertyNames{i}) )
0111 eval(['Data{i}{1}=Elements.',ElementNames{i},'.',PropertyNames{i}{1},';']);
0112 ElementCount(i) = prod(size(Data{i}{1}));
0113 Type{i} = zeros(length(PropertyNames{i}),1);
0114 else
0115 ElementCount(i) = 0;
0116 end
0117
0118 fprintf(fid,'element %s %u\n',ElementNames{i},ElementCount(i));
0119
0120 for j = 1 : length(PropertyNames{i})
0121
0122 eval(['Data{i}{j}=Elements.',ElementNames{i},'.',PropertyNames{i}{j},';']);
0123
0124 if ( ElementCount(i) ~= prod(size(Data{i}{j})) )
0125 fclose(fid);
0126 error('All property data in an element must have the same length.');
0127 end
0128
0129 if ( iscell(Data{i}{j}) )
0130 Type{i}(j) = 9;
0131 Data{i}{j} = Data{i}{j}{1};
0132 end
0133
0134 for k = 1 : length(MatlabTypeNames)
0135 if ( isa(Data{i}{j},MatlabTypeNames{k}) )
0136 Type{i}(j) = Type{i}(j) + k;
0137 break;
0138 end
0139 end
0140
0141 if ( ~rem(Type{i}(j),9) )
0142 fclose(fid);
0143 error('Unsupported data structure.');
0144 end
0145
0146
0147
0148
0149
0150 if ( Type{i}(j) <= 8 )
0151 if any(strcmp({'single','double'},MatlabTypeNames{Type{i}(j)}))
0152 if ~any(floor(Data{i}{j}) ~= Data{i}{j})
0153 MinValue = min(min(Data{i}{j}));
0154 MaxValue = max(max(Data{i}{j}));
0155
0156
0157 tmp = max(min(find(MinValue >= IntegerDataMin)),min(find(MaxValue <= IntegerDataMax)));
0158
0159 if ~isempty(tmp)
0160 Type{i}(j) = tmp;
0161 end
0162 end
0163 end
0164 else
0165 eval(['Data{i}{j}=Elements.',ElementNames{i},'.',PropertyNames{i}{j},';']);
0166 tmp = 1;
0167
0168 for k = 1:prod(size(Data{i}{j}))
0169 tmp = tmp & all(floor(Data{i}{j}{k}) == Data{i}{j}{k});
0170 end
0171
0172 if tmp
0173 MinValue = inf;
0174 MaxValue = -inf;
0175
0176 for k = 1:prod(size(Data{i}{j}))
0177 MinValue = min(MinValue,min(Data{i}{j}{k}));
0178 MaxValue = max(MaxValue,max(Data{i}{j}{k}));
0179 end
0180
0181
0182 tmp = max(min(find(MinValue >= IntegerDataMin)),min(find(MaxValue <= IntegerDataMax)));
0183
0184 if ~isempty(tmp)
0185 Type{i}(j) = tmp + 9;
0186 end
0187
0188 end
0189 end
0190
0191
0192 if rem(Type{i}(j),9) == 8 & ~strcmpi(Str,'double')
0193 Type{i}(j) = Type{i}(j) - 1;
0194 end
0195
0196 if Type{i}(j) <= 8
0197 fprintf(fid,'property %s %s\n',PlyTypeNames{Type{i}(j)},PropertyNames{i}{j});
0198 else
0199 fprintf(fid,'property list uchar %s %s\n',PlyTypeNames{Type{i}(j)-9},PropertyNames{i}{j});
0200 end
0201 end
0202 end
0203
0204 fprintf(fid,'end_header\n');
0205
0206 switch Format
0207 case 'ascii'
0208 Format = 0;
0209 case 'binary_little_endian'
0210 fclose(fid);
0211 fid = fopen(Path,'a','ieee-le');
0212 Format = 1;
0213 case 'binary_big_endian'
0214 fclose(fid);
0215 fid = fopen(Path,'a','ieee-be');
0216 Format = 2;
0217 end
0218
0219 for i = 1 : NumElements
0220 if ~isempty(PropertyNames{i})
0221 if ~Format
0222 for k = 1:ElementCount(i)
0223 for j = 1:length(PropertyNames{i})
0224 if Type{i}(j) <= 8
0225 fprintf(fid,[PrintfTypeChar{Type{i}(j)},' '],Data{i}{j}(k));
0226 else
0227 fprintf(fid,'%u%s ',length(Data{i}{j}{k}),sprintf([' ',PrintfTypeChar{Type{i}(j)-9}],Data{i}{j}{k}));
0228 end
0229 end
0230
0231 fprintf(fid,'\n');
0232 end
0233 else
0234 if all(Type{i} <= 8) & all(Type{i} == Type{i}(1))
0235
0236 tmp = zeros(length(PropertyNames{i}),ElementCount(i));
0237
0238 for j = 1:length(PropertyNames{i})
0239 tmp(j,:) = Data{i}{j}(:)';
0240 end
0241
0242 fwrite(fid,tmp,FWriteTypeNames{Type{i}(j)});
0243 elseif all(Type{i} > 8)
0244
0245 Type{i} = Type{i} - 9;
0246
0247 if length(PropertyNames{i}) == 1
0248
0249 tmp = FWriteTypeNames{Type{i}(1)};
0250
0251 for k = 1:ElementCount(i)
0252 fwrite(fid,length(Data{i}{1}{k}),'uchar');
0253 fwrite(fid,Data{i}{1}{k},tmp);
0254 end
0255 else
0256
0257 for k = 1:ElementCount(i)
0258 for j = 1:length(PropertyNames{i})
0259 fwrite(fid,length(Data{i}{j}{k}),'uchar');
0260 fwrite(fid,Data{i}{j}{k},FWriteTypeNames{Type{i}(j)});
0261 end
0262 end
0263 end
0264 else
0265
0266 for k = 1:ElementCount(i)
0267 for j = 1:length(PropertyNames{i})
0268 if Type{i}(j) <= 8
0269 fwrite(fid,Data{i}{j}(k),FWriteTypeNames{Type{i}(j)});
0270 else
0271 fwrite(fid,length(Data{i}{j}{k}),'uchar');
0272 fwrite(fid,Data{i}{j}{k},FWriteTypeNames{Type{i}(j)-9});
0273 end
0274 end
0275 end
0276 end
0277 end
0278 end
0279 end
0280
0281 fclose(fid);
0282
0283 return
0284 end