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