0023404: Create SquareConfusion function in Precision package for speed and convenience
[occt.git] / src / Voxel / Voxel_Writer.cxx
CommitLineData
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
27Voxel_Writer::Voxel_Writer():myFormat(Voxel_VFF_ASCII),myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0)
28{
29
30}
31
32void Voxel_Writer::SetFormat(const Voxel_VoxelFileFormat format)
33{
34 myFormat = format;
35}
36
37void Voxel_Writer::SetVoxels(const Voxel_BoolDS& voxels)
38{
39 myBoolVoxels = (Standard_Address) &voxels;
40 myColorVoxels = 0;
41 myFloatVoxels = 0;
42}
43
44void Voxel_Writer::SetVoxels(const Voxel_ColorDS& voxels)
45{
46 myBoolVoxels = 0;
47 myColorVoxels = (Standard_Address) &voxels;
48 myFloatVoxels = 0;
49}
50
51void Voxel_Writer::SetVoxels(const Voxel_FloatDS& voxels)
52{
53 myBoolVoxels = 0;
54 myColorVoxels = 0;
55 myFloatVoxels = (Standard_Address) &voxels;
56}
57
58Standard_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
86Standard_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
145Standard_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
204Standard_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
263Standard_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
323Standard_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
383Standard_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}