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
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
|
//--------------------------------------
//--- 010 Editor v6.0.3 Binary Template
//
// File: ctb
// Author: Tim Slater
// Revision: 1
// Purpose: CTB File Format
//--------------------------------------
struct HEADER {
uint Magic <fgcolor=cBlack, bgcolor=cRed, format=hex>;
uint HeaderSize <fgcolor=cBlack, bgcolor=cRed>;
uint HeaderOffset <fgcolor=cBlack, bgcolor=cRed, format=hex>;
uint unknown1;
uint unknown2;
uint SignatureSize <fgcolor=cBlack, bgcolor=cRed>;
uint SignatureOffset <fgcolor=cBlack, bgcolor=cRed, format=hex>;
uint unknown3;
ushort unknown4;
ushort unknown5;
uint unknown6;
uint unknown7;
uint unknown9;
} header;
FSeek(header.HeaderOffset);
struct DECRYPTED_HEADER {
uint64 ChecksumValue;
uint LayerTableOffset;
float DisplayWidth;
float DisplayHeight;
float MachineZ;
uint Padding1;
uint Padding2;
float TotalHeightMilimeter;
float LayerHeight;
float ExposureTime;
float BottomExposureTime;
float LightOffDelay;
uint BottomLayerCount;
uint ResolutionX;
uint ResolutionY;
uint LayerCount;
uint LargePreviewOffset;
uint SmallPreviewOffset;
uint PrintTime;
uint ProjectorType;
float BottomLiftHeight;
float BottomLiftSpeed;
float LiftHeight;
float LiftSpeed;
float RetractSpeed; /* might be bottom retract speed, need to verify */
float ModelVolume;
float ModelWeight;
float Cost;
float BottomLightOffDelay;
uint unknown9;
ushort LightPWM; /* these might be in the wrong order */
ushort BottomLightPWM;
uint LayerXorKey;
float BottomLiftHeight2;
float BottomLiftSpeed2;
float LiftingHeight2;
float LiftingSpeed2;
float RetractHeight2;
float RetractSpeed2;
float RestTimeAfterLift;
uint PrinterNameOffset;
uint PrinterNameSize;
uint unknown12;
uint unknown13;
uint unknown14;
float RestTimeAfterRetract;
float RestTimeAfterLift;
uint unknown15;
float BottomRetractSpeed;
float BottomRetractSpeed2;
uint Padding1;
float Four1;
uint Padding2;
float Four2;
float RestTimeAfterRetract;
float RestTimeAfterLift;
float RestTimeBeforeLift;
float BottomRetractHeight;
float unknown23;
uint unknown24;
uint unknown25;
uint LastLayerIndex;
uint unknown26[4];
uint DisclaimerOffset;
uint DisclaimerSize;
uint Padding3;
uint Padding4;
uint Padding5;
uint Padding6;
};
DECRYPTED_HEADER decryptedHeader;
struct PREVIEW {
uint ResolutionX <fgcolor=cBlack, bgcolor=cRed>;
uint ResolutionY <fgcolor=cBlack, bgcolor=cRed>;
uint ImageOffset <fgcolor=cBlack, bgcolor=cRed>;
uint ImageLength <fgcolor=cBlack, bgcolor=cRed>;
byte Data[ImageLength] <fgcolor=cBlack, bgcolor=cGreen>;
} LargePreview;
PREVIEW SmallPreview;
FSeek(decryptedHeader.PrinterNameOffset);
char MachineName[decryptedHeader.PrinterNameSize] <fgcolor=cBlack, bgcolor=cYellow>;
char Disclaimer[320] <fgcolor=cBlack, bgcolor=cPurple>;
FSeek(decryptedHeader.LayerTableOffset);
/* need to walk the layer index table to get a count of them.
the actual count field is in the encrypted header */
struct LAYER_POINTER {
uint Offset;
uint Padding1;
uint LayerTableSize;
uint Padding2;
} layerPointers[decryptedHeader.LayerCount];
struct LAYER_HEADER{
uint LayerMarker <hidden=true>;
float PositionZ;
float ExposureTime;
float LightOffDelay;
uint LayerDataOffset;
uint unknown2;
uint LayerDataLength;
uint unknown3;
uint EncryptedDataOffset;
uint EncryptedDataLength;
float LiftHeight;
float LiftSpeed;
float LiftHeight2;
float LiftSpeed2;
float RetractSpeed;
float RetractHeight2;
float RetractSpeed2;
float RestTimeBeforeLift;
float RestTimeAfterLift;
float RestTimeAfterRetract;
float LightPWM; /* just a guess, has value 255 as a float */
uint unknown6;
};
struct LAYER {
LAYER_HEADER layerHeader;
FSeek(layerHeader.LayerDataOffset);
/* do we have encrypted data? */
if (layerHeader.EncryptedDataLength > 0) {
if (layerHeader.EncryptedDataOffset > 0) {
ubyte normalLayerData1[layerHeader.EncryptedDataOffset];
ubyte encrytedLayerData[layerHeader.EncryptedDataLength];
ubyte normalLayerData2[layerHeader.LayerDataLength - (layerHeader.EncryptedDataOffset + layerHeader.EncryptedDataLength)];
} else {
ubyte encrytedLayerData[layerHeader.EncryptedDataLength];
ubyte normalLayerData[layerHeader.LayerDataLength - layerHeader.EncryptedDataLength];
}
} else {
ubyte layerData[layerHeader.LayerDataLength] <format=binary>;
}
};
struct LAYERS {
local uint x;
for(x = 0; x < decryptedHeader.LayerCount; x++) {
FSeek(layerPointers[x].Offset);
LAYER layer;
}
} layers;
ubyte Sha256Hash[0x20]<format=hex>;
|