b311480e |
1 | // Created on: 2008-08-28 |
2 | // Created by: Vladislav ROMASHKO |
973c2be1 |
3 | // Copyright (c) 2008-2014 OPEN CASCADE SAS |
b311480e |
4 | // |
973c2be1 |
5 | // This file is part of Open CASCADE Technology software library. |
b311480e |
6 | // |
d5f74e42 |
7 | // This library is free software; you can redistribute it and/or modify it under |
8 | // the terms of the GNU Lesser General Public License version 2.1 as published |
973c2be1 |
9 | // by the Free Software Foundation, with special exception defined in the file |
10 | // OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT |
11 | // distribution for complete text of the license and disclaimer of any warranty. |
b311480e |
12 | // |
973c2be1 |
13 | // Alternatively, this file may be used under the terms of Open CASCADE |
14 | // commercial license or contractual agreement. |
7fd59977 |
15 | |
16 | #include <Voxel_Writer.ixx> |
17 | #include <Voxel_TypeDef.hxx> |
18 | |
19 | #include <Precision.hxx> |
20 | #include <TCollection_AsciiString.hxx> |
94708556 |
21 | #include <OSD_OpenFile.hxx> |
7fd59977 |
22 | |
23 | Voxel_Writer::Voxel_Writer():myFormat(Voxel_VFF_ASCII),myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0) |
24 | { |
25 | |
26 | } |
27 | |
28 | void Voxel_Writer::SetFormat(const Voxel_VoxelFileFormat format) |
29 | { |
30 | myFormat = format; |
31 | } |
32 | |
33 | void Voxel_Writer::SetVoxels(const Voxel_BoolDS& voxels) |
34 | { |
35 | myBoolVoxels = (Standard_Address) &voxels; |
36 | myColorVoxels = 0; |
37 | myFloatVoxels = 0; |
38 | } |
39 | |
40 | void Voxel_Writer::SetVoxels(const Voxel_ColorDS& voxels) |
41 | { |
42 | myBoolVoxels = 0; |
43 | myColorVoxels = (Standard_Address) &voxels; |
44 | myFloatVoxels = 0; |
45 | } |
46 | |
47 | void Voxel_Writer::SetVoxels(const Voxel_FloatDS& voxels) |
48 | { |
49 | myBoolVoxels = 0; |
50 | myColorVoxels = 0; |
51 | myFloatVoxels = (Standard_Address) &voxels; |
52 | } |
53 | |
54 | Standard_Boolean Voxel_Writer::Write(const TCollection_ExtendedString& file) const |
55 | { |
56 | switch (myFormat) |
57 | { |
58 | case Voxel_VFF_ASCII: |
59 | { |
60 | if (myBoolVoxels) |
61 | return WriteBoolAsciiVoxels(file); |
62 | else if (myColorVoxels) |
63 | return WriteColorAsciiVoxels(file); |
64 | else if (myFloatVoxels) |
65 | return WriteFloatAsciiVoxels(file); |
66 | } |
67 | case Voxel_VFF_BINARY: |
68 | { |
69 | if (myBoolVoxels) |
70 | return WriteBoolBinaryVoxels(file); |
71 | else if (myColorVoxels) |
72 | return WriteColorBinaryVoxels(file); |
73 | else if (myFloatVoxels) |
74 | return WriteFloatBinaryVoxels(file); |
75 | } |
76 | } |
77 | |
78 | // No voxels or no format description is found: |
79 | return Standard_False; |
80 | } |
81 | |
82 | Standard_Boolean Voxel_Writer::WriteBoolAsciiVoxels(const TCollection_ExtendedString& file) const |
83 | { |
84 | Voxel_BoolDS* ds = (Voxel_BoolDS*) myBoolVoxels; |
85 | if (!ds->myData) |
86 | return Standard_False; |
87 | |
88 | // Open file for writing |
94708556 |
89 | FILE* f = OSD_OpenFile(file, "w+"); |
7fd59977 |
90 | if (!f) |
91 | return Standard_False; |
92 | |
93 | // Header: file format, type of voxels |
94 | fprintf(f, VOXELS); |
95 | fprintf(f, " "); |
96 | fprintf(f, ASCII); |
97 | fprintf(f, " "); |
98 | fprintf(f, BOOL); |
99 | fprintf(f, "\n"); |
100 | |
101 | // Location, size, number of splits |
102 | fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ()); |
103 | fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen()); |
104 | fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ()); |
105 | |
106 | // Data |
107 | // Copied from Voxel_BoolDS.cxx: |
108 | Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 8.0)); |
109 | Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0)); |
110 | // myData[0 .. nb_slices - 1][0 .. 7] |
111 | if (nb_slices) |
112 | { |
113 | Standard_Integer i1 = 0, i2 = 0; |
114 | for (i1 = 0; i1 < nb_slices; i1++) |
115 | { |
116 | if (((Standard_Byte**)ds->myData)[i1]) |
117 | { |
118 | Standard_Boolean has_value = Standard_False; |
119 | fprintf(f, "%d ", i1); // index of slice |
120 | for (i2 = 0; i2 < 8; i2++) |
121 | { |
122 | Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2]; |
123 | if (value) |
124 | { |
125 | has_value = Standard_True; |
126 | fprintf(f, "%d %d\n", i2, value); |
127 | } |
128 | } |
129 | if (!has_value) |
130 | { |
131 | fprintf(f, "0 0\n"); |
132 | } |
133 | } |
134 | } |
135 | } |
136 | |
137 | fclose(f); |
138 | return Standard_True; |
139 | } |
140 | |
141 | Standard_Boolean Voxel_Writer::WriteColorAsciiVoxels(const TCollection_ExtendedString& file) const |
142 | { |
143 | Voxel_ColorDS* ds = (Voxel_ColorDS*) myColorVoxels; |
144 | if (!ds->myData) |
145 | return Standard_False; |
146 | |
147 | // Open file for writing |
94708556 |
148 | FILE* f = OSD_OpenFile(file, "w+"); |
7fd59977 |
149 | if (!f) |
150 | return Standard_False; |
151 | |
152 | // Header: file format, type of voxels |
153 | fprintf(f, VOXELS); |
154 | fprintf(f, " "); |
155 | fprintf(f, ASCII); |
156 | fprintf(f, " "); |
157 | fprintf(f, COLOR); |
158 | fprintf(f, "\n"); |
159 | |
160 | // Location, size, number of splits |
161 | fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ()); |
162 | fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen()); |
163 | fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ()); |
164 | |
165 | // Data |
166 | // Copied from Voxel_ColorDS.cxx: |
167 | Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 2.0)); |
168 | Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0)); |
169 | // myData[0 .. nb_slices - 1][0 .. 31] |
170 | if (nb_slices) |
171 | { |
172 | Standard_Integer i1 = 0, i2 = 0; |
173 | for (i1 = 0; i1 < nb_slices; i1++) |
174 | { |
175 | if (((Standard_Byte**)ds->myData)[i1]) |
176 | { |
177 | Standard_Boolean has_value = Standard_False; |
178 | fprintf(f, "%d ", i1); // index of slice |
179 | for (i2 = 0; i2 < 32; i2++) |
180 | { |
181 | Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2]; |
182 | if (value) |
183 | { |
184 | has_value = Standard_True; |
185 | fprintf(f, "%d %d\n", i2, value); |
186 | } |
187 | } |
188 | if (!has_value) |
189 | { |
190 | fprintf(f, "0 0\n"); |
191 | } |
192 | } |
193 | } |
194 | } |
195 | |
196 | fclose(f); |
197 | return Standard_True; |
198 | } |
199 | |
200 | Standard_Boolean Voxel_Writer::WriteFloatAsciiVoxels(const TCollection_ExtendedString& file) const |
201 | { |
202 | Voxel_FloatDS* ds = (Voxel_FloatDS*) myFloatVoxels; |
203 | if (!ds->myData) |
204 | return Standard_False; |
205 | |
206 | // Open file for writing |
94708556 |
207 | FILE* f = OSD_OpenFile(file, "w+"); |
7fd59977 |
208 | if (!f) |
209 | return Standard_False; |
210 | |
211 | // Header: file format, type of voxels |
212 | fprintf(f, VOXELS); |
213 | fprintf(f, " "); |
214 | fprintf(f, ASCII); |
215 | fprintf(f, " "); |
216 | fprintf(f, FLOAT); |
217 | fprintf(f, "\n"); |
218 | |
219 | // Location, size, number of splits |
220 | fprintf(f, "%g %g %g\n", ds->GetX(), ds->GetY(), ds->GetZ()); |
221 | fprintf(f, "%g %g %g\n", ds->GetXLen(), ds->GetYLen(), ds->GetZLen()); |
222 | fprintf(f, "%d %d %d\n", ds->GetNbX(), ds->GetNbY(), ds->GetNbZ()); |
223 | |
224 | // Data |
225 | // Copied from Voxel_FloatDS.cxx: |
226 | Standard_Integer nb_floats = ds->GetNbX() * ds->GetNbY() * ds->GetNbZ(); |
227 | Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice |
228 | // myData[0 .. nb_slices - 1][0 .. 31] |
229 | if (nb_slices) |
230 | { |
231 | Standard_Integer i1 = 0, i2 = 0; |
232 | for (i1 = 0; i1 < nb_slices; i1++) |
233 | { |
234 | if (((Standard_ShortReal**)ds->myData)[i1]) |
235 | { |
236 | Standard_Boolean has_value = Standard_False; |
237 | fprintf(f, "%d ", i1); // index of slice |
238 | for (i2 = 0; i2 < 32; i2++) |
239 | { |
240 | Standard_ShortReal value = ((Standard_ShortReal*)((Standard_ShortReal**)ds->myData)[i1])[i2]; |
241 | if (value) |
242 | { |
243 | has_value = Standard_True; |
244 | fprintf(f, "%d %g\n", i2, value); |
245 | } |
246 | } |
247 | if (!has_value) |
248 | { |
249 | fprintf(f, "0 0\n"); |
250 | } |
251 | } |
252 | } |
253 | } |
254 | |
255 | fclose(f); |
256 | return Standard_True; |
257 | } |
258 | |
259 | Standard_Boolean Voxel_Writer::WriteBoolBinaryVoxels(const TCollection_ExtendedString& file) const |
260 | { |
261 | Voxel_BoolDS* ds = (Voxel_BoolDS*) myBoolVoxels; |
262 | if (!ds->myData) |
263 | return Standard_False; |
264 | |
265 | // Open file for writing |
94708556 |
266 | FILE* f = OSD_OpenFile(file, "wb"); |
7fd59977 |
267 | if (!f) |
268 | return Standard_False; |
269 | |
270 | // Header: file format, type of voxels |
271 | fprintf(f, VOXELS); |
272 | fprintf(f, " "); |
273 | fprintf(f, BINARY); |
274 | fprintf(f, " "); |
275 | fprintf(f, BOOL); |
276 | fprintf(f, "\n"); |
277 | |
278 | // Location, size, number of splits |
279 | fwrite(&(ds->myX), sizeof(Standard_Real), 1, f); |
280 | fwrite(&(ds->myY), sizeof(Standard_Real), 1, f); |
281 | fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f); |
282 | fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f); |
283 | fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f); |
284 | fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f); |
285 | fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f); |
286 | fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f); |
287 | fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f); |
288 | |
289 | // Data |
290 | // Copied from Voxel_BoolDS.cxx: |
291 | Standard_Integer nb_bytes = RealToInt(ceil(ds->GetNbX() * ds->GetNbY() * ds->GetNbZ() / 8.0)); |
292 | Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0)); |
293 | // myData[0 .. nb_slices - 1][0 .. 7] |
294 | if (nb_slices) |
295 | { |
296 | Standard_Integer i1 = 0, i2 = 0; |
297 | for (i1 = 0; i1 < nb_slices; i1++) |
298 | { |
299 | if (((Standard_Byte**)ds->myData)[i1]) |
300 | { |
301 | for (i2 = 0; i2 < 8; i2++) |
302 | { |
303 | Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2]; |
304 | if (value) |
305 | { |
306 | fwrite(&i1, sizeof(Standard_Integer), 1, f); |
307 | fwrite(&i2, sizeof(Standard_Integer), 1, f); |
308 | fwrite(&value, sizeof(Standard_Byte), 1, f); |
309 | } |
310 | } |
311 | } |
312 | } |
313 | } |
314 | |
315 | fclose(f); |
316 | return Standard_True; |
317 | } |
318 | |
319 | Standard_Boolean Voxel_Writer::WriteColorBinaryVoxels(const TCollection_ExtendedString& file) const |
320 | { |
321 | Voxel_ColorDS* ds = (Voxel_ColorDS*) myColorVoxels; |
322 | if (!ds->myData) |
323 | return Standard_False; |
324 | |
325 | // Open file for writing |
94708556 |
326 | FILE* f = OSD_OpenFile(file, "wb"); |
7fd59977 |
327 | if (!f) |
328 | return Standard_False; |
329 | |
330 | // Header: file format, type of voxels |
331 | fprintf(f, VOXELS); |
332 | fprintf(f, " "); |
333 | fprintf(f, BINARY); |
334 | fprintf(f, " "); |
335 | fprintf(f, COLOR); |
336 | fprintf(f, "\n"); |
337 | |
338 | // Location, size, number of splits |
339 | fwrite(&(ds->myX), sizeof(Standard_Real), 1, f); |
340 | fwrite(&(ds->myY), sizeof(Standard_Real), 1, f); |
341 | fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f); |
342 | fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f); |
343 | fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f); |
344 | fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f); |
345 | fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f); |
346 | fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f); |
347 | fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f); |
348 | |
349 | // Data |
350 | // Copied from Voxel_ColorDS.cxx: |
351 | Standard_Integer nb_bytes = RealToInt(ceil(ds->myNbX * ds->myNbY * ds->myNbZ / 2.0)); |
352 | Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0)); |
353 | // myData[0 .. nb_slices - 1][0 .. 31] |
354 | if (nb_slices) |
355 | { |
356 | Standard_Integer i1 = 0, i2 = 0; |
357 | for (i1 = 0; i1 < nb_slices; i1++) |
358 | { |
359 | if (((Standard_Byte**)ds->myData)[i1]) |
360 | { |
361 | for (i2 = 0; i2 < 32; i2++) |
362 | { |
363 | Standard_Byte value = ((Standard_Byte*)((Standard_Byte**)ds->myData)[i1])[i2]; |
364 | if (value) |
365 | { |
366 | fwrite(&i1, sizeof(Standard_Integer), 1, f); |
367 | fwrite(&i2, sizeof(Standard_Integer), 1, f); |
368 | fwrite(&value, sizeof(Standard_Byte), 1, f); |
369 | } |
370 | } |
371 | } |
372 | } |
373 | } |
374 | |
375 | fclose(f); |
376 | return Standard_True; |
377 | } |
378 | |
379 | Standard_Boolean Voxel_Writer::WriteFloatBinaryVoxels(const TCollection_ExtendedString& file) const |
380 | { |
381 | Voxel_FloatDS* ds = (Voxel_FloatDS*) myFloatVoxels; |
382 | if (!ds->myData) |
383 | return Standard_False; |
384 | |
385 | // Open file for writing |
94708556 |
386 | FILE* f = OSD_OpenFile(file, "wb"); |
7fd59977 |
387 | if (!f) |
388 | return Standard_False; |
389 | |
390 | // Header: file format, type of voxels |
391 | fprintf(f, VOXELS); |
392 | fprintf(f, " "); |
393 | fprintf(f, BINARY); |
394 | fprintf(f, " "); |
395 | fprintf(f, FLOAT); |
396 | fprintf(f, "\n"); |
397 | |
398 | // Location, size, number of splits |
399 | fwrite(&(ds->myX), sizeof(Standard_Real), 1, f); |
400 | fwrite(&(ds->myY), sizeof(Standard_Real), 1, f); |
401 | fwrite(&(ds->myZ), sizeof(Standard_Real), 1, f); |
402 | fwrite(&(ds->myXLen), sizeof(Standard_Real), 1, f); |
403 | fwrite(&(ds->myYLen), sizeof(Standard_Real), 1, f); |
404 | fwrite(&(ds->myZLen), sizeof(Standard_Real), 1, f); |
405 | fwrite(&(ds->myNbX), sizeof(Standard_Integer), 1, f); |
406 | fwrite(&(ds->myNbY), sizeof(Standard_Integer), 1, f); |
407 | fwrite(&(ds->myNbZ), sizeof(Standard_Integer), 1, f); |
408 | |
409 | // Data |
410 | // Copied from Voxel_FloatDS.cxx: |
411 | Standard_Integer nb_floats = ds->myNbX * ds->myNbY * ds->myNbZ; |
412 | Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice |
413 | // myData[0 .. nb_slices - 1][0 .. 31] |
414 | if (nb_slices) |
415 | { |
416 | Standard_Integer i1 = 0, i2 = 0; |
08cd2f6b |
417 | Standard_Real small = Precision::SquareConfusion(); |
7fd59977 |
418 | for (i1 = 0; i1 < nb_slices; i1++) |
419 | { |
420 | if (((Standard_ShortReal**)ds->myData)[i1]) |
421 | { |
422 | for (i2 = 0; i2 < 32; i2++) |
423 | { |
424 | Standard_ShortReal value = ((Standard_ShortReal*)((Standard_ShortReal**)ds->myData)[i1])[i2]; |
425 | if (fabs(value) > small) |
426 | { |
427 | fwrite(&i1, sizeof(Standard_Integer), 1, f); |
428 | fwrite(&i2, sizeof(Standard_Integer), 1, f); |
429 | fwrite(&value, sizeof(Standard_ShortReal), 1, f); |
430 | } |
431 | } |
432 | } |
433 | } |
434 | } |
435 | |
436 | fclose(f); |
437 | return Standard_True; |
438 | } |