0026741: Problem with building samples and demo
[occt.git] / src / Voxel / Voxel_Reader.cxx
1 // Created on: 2008-08-28
2 // Created by: Vladislav ROMASHKO
3 // Copyright (c) 2008-2014 OPEN CASCADE SAS
4 //
5 // This file is part of Open CASCADE Technology software library.
6 //
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
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.
12 //
13 // Alternatively, this file may be used under the terms of Open CASCADE
14 // commercial license or contractual agreement.
15
16
17 #include <OSD_OpenFile.hxx>
18 #include <TCollection_AsciiString.hxx>
19 #include <TCollection_ExtendedString.hxx>
20 #include <Voxel_BoolDS.hxx>
21 #include <Voxel_ColorDS.hxx>
22 #include <Voxel_FloatDS.hxx>
23 #include <Voxel_Reader.hxx>
24 #include <Voxel_TypeDef.hxx>
25 #include <Voxel_VoxelFileFormat.hxx>
26
27 Voxel_Reader::Voxel_Reader():myBoolVoxels(0),myColorVoxels(0),myFloatVoxels(0)
28 {
29
30 }
31
32 Standard_Boolean Voxel_Reader::Read(const TCollection_ExtendedString& file)
33 {
34   // Open file in ASCII mode to read header
35   FILE* f = OSD_OpenFile(file, "r");
36   if (!f)
37     return Standard_False;
38
39   // Read the header
40   Standard_Byte type; // 0 - bool, 1 - color, 2 - float
41   Voxel_VoxelFileFormat format;
42   Standard_Character svoxels[9], sformat[9], stype[9];
43   if (fscanf(f, "%8s %8s %8s\n", svoxels, sformat, stype) != 3)
44   {
45     fclose(f);
46     return Standard_False;
47   }
48   fclose(f);
49
50   // Take format, type of voxels.
51   // Voxels
52   if (strcmp(svoxels, VOXELS))
53     return Standard_False;
54   // Format
55   if (strcmp(sformat, ASCII) == 0)
56     format = Voxel_VFF_ASCII;
57   else if (strcmp(sformat, BINARY) == 0)
58     format = Voxel_VFF_BINARY;
59   else
60     return Standard_False;
61   // Type of voxels
62   if (strcmp(stype, BOOL) == 0)
63     type = 0;
64   else if (strcmp(stype, COLOR) == 0)
65     type = 1;
66   else if (strcmp(stype, FLOAT) == 0)
67     type = 2;
68   else
69     return Standard_False;
70
71   // Read the rest
72   switch (format)
73   {
74     case Voxel_VFF_ASCII:
75     {
76       switch (type)
77       {
78         case 0:
79           return ReadBoolAsciiVoxels(file);
80         case 1:
81           return ReadColorAsciiVoxels(file);
82         case 2:
83           return ReadFloatAsciiVoxels(file);
84       }
85     }
86     case Voxel_VFF_BINARY:
87     {
88       switch (type)
89       {
90         case 0:
91           return ReadBoolBinaryVoxels(file);
92         case 1:
93           return ReadColorBinaryVoxels(file);
94         case 2:
95           return ReadFloatBinaryVoxels(file);
96       }
97     }
98   }
99
100   // No voxels or no format description is found:
101   return Standard_False;
102 }
103
104 Standard_Boolean Voxel_Reader::IsBoolVoxels() const
105 {
106   return (myBoolVoxels != 0);
107 }
108
109 Standard_Boolean Voxel_Reader::IsColorVoxels() const
110 {
111   return (myColorVoxels != 0);
112 }
113
114 Standard_Boolean Voxel_Reader::IsFloatVoxels() const
115 {
116   return (myFloatVoxels != 0);
117 }
118
119 Standard_Address Voxel_Reader::GetBoolVoxels() const
120 {
121   return myBoolVoxels;
122 }
123
124 Standard_Address Voxel_Reader::GetColorVoxels() const
125 {
126   return myColorVoxels;
127 }
128
129 Standard_Address Voxel_Reader::GetFloatVoxels() const
130 {
131   return myFloatVoxels;
132 }
133
134 static Standard_Boolean has_slice(const Standard_CString line)
135 {
136   Standard_Integer i = 0, nb_spaces = 0;
137   while (line[i] != '\0')
138   {
139     if (line[i] == ' ')
140       nb_spaces++;
141     i++;
142   }
143   return (nb_spaces == 2);
144 }
145
146 Standard_Boolean Voxel_Reader::ReadBoolAsciiVoxels(const TCollection_ExtendedString& file)
147 {
148   // Open file for reading
149   FILE* f = OSD_OpenFile(file, "r");
150   if (!f)
151     return Standard_False;
152   Standard_Character line[65], sx[33], sy[33], sz[33];
153
154   // Header: skip it
155   if (fgets(line, 64, f) == NULL)
156   {
157     return Standard_False;
158   }
159
160   // Location, size, number of splits
161   Standard_Integer nbx = 0, nby = 0, nbz = 0;
162   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
163   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
164   {
165     fclose(f);
166     return Standard_False;
167   }
168   x = Atof(sx); y = Atof(sy); z = Atof(sz);
169   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
170   {
171     fclose(f);
172     return Standard_False;
173   }
174   xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
175   if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
176   {
177     fclose(f);
178     return Standard_False;
179   }
180
181   // Allocate the voxels
182   myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
183
184   // Data
185   // Copied from Voxel_BoolDS.cxx:
186   Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
187   Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
188   // myData[0 .. nb_slices - 1][0 .. 7]
189   if (nb_slices)
190   {
191     Standard_Integer i1 = 0, i2 = 0, value = 0;
192     while (!feof(f)
193          && fgets(line, 64, f) != NULL)
194     {
195       if (has_slice(line))
196       {
197         if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
198         {
199           fclose(f);
200           return Standard_False;
201         }
202       }
203       else
204       {
205         if (sscanf(line, "%d %d\n", &i2, &value) != 2)
206         {
207           fclose(f);
208           return Standard_False;
209         }
210       }
211
212       // Set value
213       if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
214       {
215         ((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] = 
216           (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
217       }
218       (((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = (Standard_Byte)value;
219     }
220   }
221
222   fclose(f);
223   return Standard_True;
224 }
225
226 Standard_Boolean Voxel_Reader::ReadColorAsciiVoxels(const TCollection_ExtendedString& file)
227 {
228   // Open file for reading
229   FILE* f = OSD_OpenFile(file, "r");
230   if (!f)
231     return Standard_False;
232   Standard_Character line[65], sx[33], sy[33], sz[33];
233
234   // Header: skip it
235   if (fgets(line, 64, f) == NULL)
236   {
237     fclose(f);
238     return Standard_False;
239   }
240
241   // Location, size, number of splits
242   Standard_Integer nbx = 0, nby = 0, nbz = 0;
243   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
244   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
245   {
246     fclose(f);
247     return Standard_False;
248   }
249   x = Atof(sx); y = Atof(sy); z = Atof(sz);
250   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
251   {
252     fclose(f);
253     return Standard_False;
254   }
255   xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
256   if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
257   {
258     fclose(f);
259     return Standard_False;
260   }
261
262   // Allocate the voxels
263   myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
264
265   // Data
266   // Copied from Voxel_ColorDS.cxx:
267   Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
268   Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
269   // myData[0 .. nb_slices - 1][0 .. 31]
270   if (nb_slices)
271   {
272     Standard_Integer i1 = 0, i2 = 0, value = 0;
273     while (!feof(f)
274          && fgets(line, 64, f) != NULL)
275     {
276       if (has_slice(line))
277       {
278         if (sscanf(line, "%d %d %d\n", &i1, &i2, &value) != 3)
279         {
280           fclose(f);
281           return Standard_False;
282         }
283       }
284       else
285       {
286         if (sscanf(line, "%d %d\n", &i2, &value) != 2)
287         {
288           fclose(f);
289           return Standard_False;
290         }
291       }
292
293       // Set value
294       if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
295       {
296         ((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] = 
297           (Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
298       }
299       (((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = (Standard_Byte)value;
300     }
301   }
302
303   fclose(f);
304   return Standard_True;
305 }
306
307 Standard_Boolean Voxel_Reader::ReadFloatAsciiVoxels(const TCollection_ExtendedString& file)
308 {
309   // Open file for reading
310   FILE* f = OSD_OpenFile(file, "r");
311   if (!f)
312     return Standard_False;
313   Standard_Character line[65], sx[33], sy[33], sz[33];
314
315   // Header: skip it
316   if (fgets(line, 64, f) == NULL)
317   {
318     fclose(f);
319     return Standard_False;
320   }
321
322   // Location, size, number of splits
323   Standard_Integer nbx = 0, nby = 0, nbz = 0;
324   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
325   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
326   {
327     fclose(f);
328     return Standard_False;
329   }
330   x = Atof(sx); y = Atof(sy); z = Atof(sz);
331   if (fscanf(f, "%32s %32s %32s\n", sx, sy, sz) != 3)
332   {
333     fclose(f);
334     return Standard_False;
335   }
336   xlen = Atof(sx); ylen = Atof(sy); zlen = Atof(sz);
337   if (fscanf(f, "%d %d %d\n", &nbx, &nby, &nbz) != 3)
338   {
339     fclose(f);
340     return Standard_False;
341   }
342
343   // Allocate the voxels
344   myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
345
346   // Data
347   // Copied from Voxel_FloatDS.cxx:
348   Standard_Integer nb_floats = nbx * nby * nbz;
349   Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
350   // myData[0 .. nb_slices - 1][0 .. 31]
351   if (nb_slices)
352   {
353     Standard_Integer i1 = 0, i2 = 0;
354     Standard_ShortReal value = 0.0;
355     while (!feof(f)
356          && fgets(line, 64, f) != NULL)
357     {
358       if (has_slice(line))
359       {
360         if (sscanf(line, "%d %d %64s\n", &i1, &i2, line) != 3)
361         {
362           fclose(f);
363           return Standard_False;
364         }
365       }
366       else
367       {
368         if (sscanf(line, "%d %64s\n", &i2, line) != 2)
369         {
370           fclose(f);
371           return Standard_False;
372         }
373       }
374       value = (Standard_ShortReal)Atof(line);
375
376       // Set value
377       if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
378       {
379         ((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] = 
380           (Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
381       }
382       (((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
383     }
384   }
385
386   fclose(f);
387   return Standard_True;
388 }
389
390 Standard_Boolean Voxel_Reader::ReadBoolBinaryVoxels(const TCollection_ExtendedString& file)
391 {
392   // Open file for reading
393   FILE* f = OSD_OpenFile(file, "r");
394   if (!f)
395     return Standard_False;
396
397   // Header: skip it
398   Standard_Character line[65];
399   if (fgets(line, 64, f) == NULL)
400   {
401     fclose(f);
402     return Standard_False;
403   }
404
405   // Location, size, number of splits
406   Standard_Integer nbx = 0, nby = 0, nbz = 0;
407   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
408   if (fread(&x,    sizeof(Standard_Real),    1, f) != 1
409    || fread(&y,    sizeof(Standard_Real),    1, f) != 1
410    || fread(&z,    sizeof(Standard_Real),    1, f) != 1
411    || fread(&xlen, sizeof(Standard_Real),    1, f) != 1
412    || fread(&ylen, sizeof(Standard_Real),    1, f) != 1
413    || fread(&zlen, sizeof(Standard_Real),    1, f) != 1
414    || fread(&nbx,  sizeof(Standard_Integer), 1, f) != 1
415    || fread(&nby,  sizeof(Standard_Integer), 1, f) != 1
416    || fread(&nbz,  sizeof(Standard_Integer), 1, f) != 1)
417   {
418     fclose(f);
419     return Standard_False;
420   }
421
422   // Allocate the voxels
423   myBoolVoxels = (Standard_Address) new Voxel_BoolDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
424
425   // Data
426   // Copied from Voxel_BoolDS.cxx:
427   Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 8.0));
428   Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 8.0));
429   // myData[0 .. nb_slices - 1][0 .. 7]
430   if (nb_slices)
431   {
432     Standard_Integer i1 = 0, i2 = 0, value = 0;
433     while (!feof(f)
434          && fread(&i1, sizeof(Standard_Integer), 1, f) == 1
435          && fread(&i2, sizeof(Standard_Integer), 1, f) == 1
436          && fread(&value, sizeof(Standard_Byte), 1, f) == 1)
437     {
438       // Set value
439       if (!((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])
440       {
441         ((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1] =
442           (Standard_Byte*) calloc(8/*number of bytes in slice*/, sizeof(Standard_Byte));
443       }
444       (((Standard_Byte**)((Voxel_DS*)myBoolVoxels)->myData)[i1])[i2] = (Standard_Byte)value;
445     }
446   }
447
448   fclose(f);
449   return Standard_True;
450 }
451
452 Standard_Boolean Voxel_Reader::ReadColorBinaryVoxels(const TCollection_ExtendedString& file)
453 {
454   // Open file for reading
455   FILE* f = OSD_OpenFile(file, "r");
456   if (!f)
457     return Standard_False;
458
459   // Header: skip it
460   Standard_Character line[65];
461   if (fgets(line, 64, f) == NULL)
462   {
463     fclose(f);
464     return Standard_False;
465   }
466
467   // Location, size, number of splits
468   Standard_Integer nbx = 0, nby = 0, nbz = 0;
469   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
470   if (fread(&x,    sizeof(Standard_Real),    1, f) != 1
471    || fread(&y,    sizeof(Standard_Real),    1, f) != 1
472    || fread(&z,    sizeof(Standard_Real),    1, f) != 1
473    || fread(&xlen, sizeof(Standard_Real),    1, f) != 1
474    || fread(&ylen, sizeof(Standard_Real),    1, f) != 1
475    || fread(&zlen, sizeof(Standard_Real),    1, f) != 1
476    || fread(&nbx,  sizeof(Standard_Integer), 1, f) != 1
477    || fread(&nby,  sizeof(Standard_Integer), 1, f) != 1
478    || fread(&nbz,  sizeof(Standard_Integer), 1, f) != 1)
479   {
480     fclose(f);
481     return Standard_False;
482   }
483
484   // Allocate the voxels
485   myColorVoxels = (Standard_Address) new Voxel_ColorDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
486
487   // Data
488   // Copied from Voxel_ColorDS.cxx:
489   Standard_Integer nb_bytes = RealToInt(ceil(nbx * nby * nbz / 2.0));
490   Standard_Integer nb_slices = RealToInt(ceil(nb_bytes / 32.0));
491   // myData[0 .. nb_slices - 1][0 .. 31]
492   if (nb_slices)
493   {
494     Standard_Integer i1 = 0, i2 = 0, value = 0;
495     while (!feof(f)
496          && fread(&i1, sizeof(Standard_Integer), 1, f) == 1
497          && fread(&i2, sizeof(Standard_Integer), 1, f) == 1
498          && fread(&value, sizeof(Standard_Byte), 1, f) == 1)
499     {
500       // Set value
501       if (!((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])
502       {
503         ((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1] = 
504           (Standard_Byte*) calloc(32/*number of bytes in slice*/, sizeof(Standard_Byte));
505       }
506       (((Standard_Byte**)((Voxel_DS*)myColorVoxels)->myData)[i1])[i2] = (Standard_Byte)value;
507     }
508   }
509
510   fclose(f);
511   return Standard_True;
512 }
513
514 Standard_Boolean Voxel_Reader::ReadFloatBinaryVoxels(const TCollection_ExtendedString& file)
515 {
516   // Open file for reading
517   FILE* f = OSD_OpenFile(file, "r");
518   if (!f)
519     return Standard_False;
520
521   // Header: skip it
522   Standard_Character line[65];
523   if (fgets(line, 64, f) == NULL)
524   {
525     fclose(f);
526     return Standard_False;
527   }
528
529   // Location, size, number of splits
530   Standard_Integer nbx = 0, nby = 0, nbz = 0;
531   Standard_Real x = 0.0, y = 0.0, z = 0.0, xlen = 0.0, ylen = 0.0, zlen = 0.0;
532   if (fread(&x,    sizeof(Standard_Real),    1, f) != 1
533    || fread(&y,    sizeof(Standard_Real),    1, f) != 1
534    || fread(&z,    sizeof(Standard_Real),    1, f) != 1
535    || fread(&xlen, sizeof(Standard_Real),    1, f) != 1
536    || fread(&ylen, sizeof(Standard_Real),    1, f) != 1
537    || fread(&zlen, sizeof(Standard_Real),    1, f) != 1
538    || fread(&nbx,  sizeof(Standard_Integer), 1, f) != 1
539    || fread(&nby,  sizeof(Standard_Integer), 1, f) != 1
540    || fread(&nbz,  sizeof(Standard_Integer), 1, f) != 1)
541   {
542     fclose(f);
543     return Standard_False;
544   }
545
546   // Allocate the voxels
547   myFloatVoxels = (Standard_Address) new Voxel_FloatDS(x, y, z, xlen, ylen, zlen, nbx, nby, nbz);
548
549   // Data
550   // Copied from Voxel_FloatDS.cxx:
551   Standard_Integer nb_floats = nbx * nby * nbz;
552   Standard_Integer nb_slices = RealToInt(ceil(nb_floats / 32.0)); // 32 values in 1 slice
553   // myData[0 .. nb_slices - 1][0 .. 31]
554   if (nb_slices)
555   {
556     Standard_Integer i1 = 0, i2 = 0;
557     Standard_ShortReal value = 0.0;
558     while (!feof(f)
559          && fread(&i1,    sizeof(Standard_Integer),   1, f) == 1
560          && fread(&i2,    sizeof(Standard_Integer),   1, f) == 1
561          && fread(&value, sizeof(Standard_ShortReal), 1, f) == 1)
562     {
563       // Set value
564       if (!((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])
565       {
566         ((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1] = 
567           (Standard_ShortReal*) calloc(32/*number of floats in slice*/, sizeof(Standard_ShortReal));
568       }
569       (((Standard_ShortReal**)((Voxel_DS*)myFloatVoxels)->myData)[i1])[i2] = value;
570     }
571   }
572
573   fclose(f);
574   return Standard_True;
575 }