-
Notifications
You must be signed in to change notification settings - Fork 7
/
writeMz3.m
executable file
·131 lines (129 loc) · 4.97 KB
/
writeMz3.m
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
function writeMz3(filename, face, vertex,vertexColors,alpha)
%function writeNv(vertex,faces,filename)
% --- save Face/Vertex data as Surfice MZ3 format file
%inputs:
% vertex: Vx3 array with X,Y,Z coordinates of each vertex
% vertexColors: Vx0 (empty), Vx1 (scalar) or Vx3 (RGB) colors for each vertex
% face: Vx3 triangle list indexed from 1, e.g. 1,2,3 is triangle connecting first 3 vertices
% filename: name to save object
% alpha: (optional) if provided, sets transparency of vertex colors, range 0..1
%Example
% [f,v,c] = fileUtils.ply.readPly('stroke.ply');
% fileUtils.mz3.writeMz3('stroke.mz3',f,v,c)
%MZ3 format specifications:
% Faces indexed from 0: a triangle of the first 3 vertices is 0,1,2
% Always LITTLE endian
% First two bytes are a signature for detecting format, next two bytes reveal features and version
% Optionally: may be GZ compressed (read first two bytes to detect: GZip = 0x1f8B, raw = 0x4D5A )
% HEADER: first 32 bytes
% bytes : type : notes
% 0-1: UINT16 : MAGIC signature hex = 0x4D5A integer = 23117, ASCII = 'MZ'
% 2-3: UINT16 : ATTR attributes bitfield reporting stored data (value larger than 15 indicates future version):
% bitand(ATTR,1) = 1 : isFACE File includes FACE indices
% bitand(ATTR,2) = 2 : isVERT File includes VERT vertices
% bitand(ATTR,4) = 4 : isRGBA File includes RGBA values (one per vertex)
% bitand(ATTR,8) = 8 : isSCALAR File includes SCALAR values (one per vertex)
% 4-7: UINT32 : NFACE number of faces (one face per triangle)
% 8-11: UINT32 : NVERT number of vertices
% 12-15: UINT32 : NSKIP bytes to skip (0 for current version)
% The header is 16+NSKIP bytes long
% Note: for better compression integer data is transposed (interleaved)
% FACE DATA: if isFACE, next 12*NFACE bytes
% +0..3: INT32 : 1st index of 1st triangle
% +0..3: INT32 : 1st index of 2nd triangle
% +0..3: INT32 : 1st index of 3rd triangle
% ....
% ++ INT32 : 3rd index of NVERT triangle
% VERTEX DATA: if isVERT, next 12*NVERT bytes
% +0..3: FLOAT32 : X of first vertex
% +4..7: FLOAT32 : Y of first vertex
% +8..11: FLOAT32 : Z of first vertex
% +12..15: FLOAT32 : X of second vertex
% ....
% ++ INT32 : Z of NVERT triangle
% RGBA DATA: if isRGBA next 4*NVERT bytes
% +0: UINT8: red for first vertex
% +1: UINT8: red for 2nd vertex
% ...
% ++ UINT8 : red for NVERT vertex
% ++: UINT8: green for first vertex
% ++: UINT8: green for 2nd vertex
% ...
% ++ UINT8 : green for NVERT vertex
% ++: UINT8: blue for first vertex
% ++: UINT8: blue for 2nd vertex
% ...
% ++ UINT8 : blue for NVERT vertex
% ++: UINT8: alpha for first vertex
% ++: UINT8: alpha for 2nd vertex
% ...
% ++ UINT8 : alpha for NVERT vertex
% SCALAR DATA: if isSCALAR next 4*NVERT bytes
% +0..3: FLOAT32: intensity for first vertex
% +4..7: FLOAT32: intensity for 2nd vertex
% +8..11: FLOAT32: intensity for 3rd vertex
% ...
% ++ FLOAT32 : intensity for NVERT vertex
if ~exist('vertexColors','var'), vertexColors = []; end;
if isempty(vertex) && isempty(vertexColors) && isempty(face), return; end;
if isempty(face)
nFace = 0;
else
nFace = size(face,1);
end
isFace = (nFace > 0);
if isempty(vertex)
nVert = 0;
else
nVert = size(vertex,1);
end
isVert = (nVert > 0);
isRGBA = false;
if ~isempty(vertexColors) && (size(vertexColors,2) == 3)
isRGBA = true;
if (nVert > 0) && (size(vertexColors,1) ~= nVert), error('Number of vertices and colors must match'); end;
nVert = size(vertexColors,1);
end
isScalar = false;
if ~isempty(vertexColors) && (size(vertexColors,2) == 1)
isScalar = true;
if (nVert > 0) && (size(vertexColors,1) ~= nVert), error('Number of vertices and colors must match'); end;
nVert = size(vertexColors,1);
end
[fid,Msg] = fopen(filename,'Wb', 'l');
if fid == -1, error(Msg); end;
%write header
attr = 0;
if isFace, attr = attr + 1; end;
if isVert, attr = attr + 2; end;
if isRGBA, attr = attr + 4; end;
if isScalar, attr = attr + 8; end;
fwrite(fid, 23117, 'uint16'); %MAGIC SIG to catch ftp conversion errors http://en.wikipedia.org/wiki/Portable_Network_Graphics
fwrite(fid, attr, 'uint16'); %attr = ATTRIBUTES
fwrite(fid, nFace, 'uint32'); %nFace
fwrite(fid, nVert, 'uint32'); %nVert
fwrite(fid, 0, 'uint32'); %nSkip - bytes to skip
if isFace
face = face - 1; %this format indexes from 0
fwrite(fid,face','int32'); %triangle indices
end
if isVert
fwrite(fid,vertex','float32'); %vertex coordinates
end;
if isRGBA
if ~exist('alpha','var'), alpha = 1.0; end;
a = ones(size(vertexColors,1),1) * alpha;
vertexColors = [vertexColors, a] * 255; %save 0..255
fwrite(fid,vertexColors','uint8'); %vertex coordinates
end;
if isScalar
fwrite(fid,vertexColors,'float32'); %vertex coordinates
end
fclose(fid);
%compress data
% system(sprintf('/Users/rorden/Downloads/zopfli-master/zopfli -i100 %s', filename));
% system(sprintf('gzip -9 %s', filename));
gzip(filename); %compress
% delete(filename); %delete uncompressed
movefile([filename '.gz'], filename); %rename
%end writeMz3()