0023404: Create SquareConfusion function in Precision package for speed and convenience
[occt.git] / src / Voxel / Voxel_Writer.cxx
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
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;
421     Standard_Real small = Precision::SquareConfusion();
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 }