Field3D
SparseFieldIO.cpp
Go to the documentation of this file.
1 //----------------------------------------------------------------------------//
2 
3 /*
4  * Copyright (c) 2009 Sony Pictures Imageworks Inc
5  *
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  *
12  * Redistributions of source code must retain the above copyright
13  * notice, this list of conditions and the following disclaimer.
14  * Redistributions in binary form must reproduce the above copyright
15  * notice, this list of conditions and the following disclaimer in the
16  * documentation and/or other materials provided with the
17  * distribution. Neither the name of Sony Pictures Imageworks nor the
18  * names of its contributors may be used to endorse or promote
19  * products derived from this software without specific prior written
20  * permission.
21  *
22  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
23  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
24  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
25  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
26  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
27  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
28  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
29  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
30  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
31  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
33  * OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35 
36 //----------------------------------------------------------------------------//
37 
42 //----------------------------------------------------------------------------//
43 
44 #include <boost/intrusive_ptr.hpp>
45 
46 #include "SparseFieldIO.h"
47 #include "Types.h"
48 
49 //----------------------------------------------------------------------------//
50 
51 using namespace boost;
52 using namespace std;
53 
54 //----------------------------------------------------------------------------//
55 
57 
58 //----------------------------------------------------------------------------//
59 // Field3D namespaces
60 //----------------------------------------------------------------------------//
61 
62 using namespace Exc;
63 using namespace Hdf5Util;
64 
65 //----------------------------------------------------------------------------//
66 // Static members
67 //----------------------------------------------------------------------------//
68 
70 const std::string SparseFieldIO::k_versionAttrName("version");
71 const std::string SparseFieldIO::k_extentsStr("extents");
72 const std::string SparseFieldIO::k_dataWindowStr("data_window");
73 const std::string SparseFieldIO::k_componentsStr("components");
74 const std::string SparseFieldIO::k_dataStr("data");
75 const std::string SparseFieldIO::k_blockOrderStr("block_order");
76 const std::string SparseFieldIO::k_numBlocksStr("num_blocks");
77 const std::string SparseFieldIO::k_blockResStr("block_res");
78 const std::string SparseFieldIO::k_bitsPerComponentStr("bits_per_component");
79 const std::string SparseFieldIO::k_numOccupiedBlocksStr("num_occupied_blocks");
80 
81 //----------------------------------------------------------------------------//
82 
84 SparseFieldIO::read(hid_t layerGroup, const std::string &filename,
85  const std::string &layerPath,
86  DataTypeEnum typeEnum)
87 {
88  Box3i extents, dataW;
89  int components;
90  int blockOrder;
91  int numBlocks;
92  V3i blockRes;
93 
94  if (layerGroup == -1) {
95  Msg::print(Msg::SevWarning, "Bad layerGroup.");
96  return FieldBase::Ptr();
97  }
98 
99  int version;
100  if (!readAttribute(layerGroup, k_versionAttrName, 1, version))
101  throw MissingAttributeException("Couldn't find attribute: " +
102  k_versionAttrName);
103 
104  if (version != k_versionNumber)
105  throw UnsupportedVersionException("SparseField version not supported: " +
106  lexical_cast<std::string>(version));
107 
108  if (!readAttribute(layerGroup, k_extentsStr, 6, extents.min.x))
109  throw MissingAttributeException("Couldn't find attribute: " +
110  k_extentsStr);
111 
112  if (!readAttribute(layerGroup, k_dataWindowStr, 6, dataW.min.x))
113  throw MissingAttributeException("Couldn't find attribute: " +
114  k_dataWindowStr);
115 
116  if (!readAttribute(layerGroup, k_componentsStr, 1, components))
117  throw MissingAttributeException("Couldn't find attribute: " +
118  k_componentsStr);
119 
120  // Read block order
121  if (!readAttribute(layerGroup, k_blockOrderStr, 1, blockOrder))
122  throw MissingAttributeException("Couldn't find attribute: " +
123  k_blockOrderStr);
124 
125  // Read number of blocks total
126  if (!readAttribute(layerGroup, k_numBlocksStr, 1, numBlocks))
127  throw MissingAttributeException("Couldn't find attribute: " +
128  k_numBlocksStr);
129 
130  // Read block resolution in each dimension
131  if (!readAttribute(layerGroup, k_blockResStr, 3, blockRes.x))
132  throw MissingAttributeException("Couldn't find attribute: " +
133  k_blockResStr);
134 
135  // ... Check that it matches the # reported by summing the active blocks
136 
137  int numCalculatedBlocks = blockRes.x * blockRes.y * blockRes.z;
138  if (numCalculatedBlocks != numBlocks)
139  throw FileIntegrityException("Incorrect block count in SparseFieldIO::read");
140 
141  // Call the appropriate read function based on the data type ---
142 
143  FieldBase::Ptr result;
144 
145  int occupiedBlocks;
146  if (!readAttribute(layerGroup, k_numOccupiedBlocksStr, 1, occupiedBlocks))
147  throw MissingAttributeException("Couldn't find attribute: " +
148  k_numOccupiedBlocksStr);
149 
150  // Check the data type ---
151 
152  int bits;
153  if (!readAttribute(layerGroup, k_bitsPerComponentStr, 1, bits))
154  throw MissingAttributeException("Couldn't find attribute: " +
155  k_bitsPerComponentStr);
156 
157  bool isHalf = false;
158  bool isFloat = false;
159  bool isDouble = false;
160 
161  switch (bits) {
162  case 16:
163  isHalf = true;
164  break;
165  case 64:
166  isDouble = true;
167  break;
168  case 32:
169  default:
170  isFloat = true;
171  }
172 
173  // Finally, read the data ---
174 
175  if (components == 1) {
176  if (isHalf && typeEnum == DataTypeHalf) {
178  field->setSize(extents, dataW);
179  field->setBlockOrder(blockOrder);
180  readData<half>(layerGroup, numBlocks, filename, layerPath, field);
181  result = field;
182  } else if (isFloat && typeEnum == DataTypeFloat) {
184  field->setSize(extents, dataW);
185  field->setBlockOrder(blockOrder);
186  readData<float>(layerGroup, numBlocks, filename, layerPath, field);
187  result = field;
188  } else if (isDouble && typeEnum == DataTypeDouble) {
190  field->setSize(extents, dataW);
191  field->setBlockOrder(blockOrder);
192  readData<double>(layerGroup, numBlocks, filename, layerPath, field);
193  result = field;
194  }
195  } else if (components == 3) {
196  if (isHalf && typeEnum == DataTypeVecHalf) {
198  field->setSize(extents, dataW);
199  field->setBlockOrder(blockOrder);
200  readData<V3h>(layerGroup, numBlocks, filename, layerPath, field);
201  result = field;
202  } else if (isFloat && typeEnum == DataTypeVecFloat) {
204  field->setSize(extents, dataW);
205  field->setBlockOrder(blockOrder);
206  readData<V3f>(layerGroup, numBlocks, filename, layerPath, field);
207  result = field;
208  } else if (isDouble && typeEnum == DataTypeVecDouble) {
210  field->setSize(extents, dataW);
211  field->setBlockOrder(blockOrder);
212  readData<V3d>(layerGroup, numBlocks, filename, layerPath, field);
213  result = field;
214  }
215  }
216 
217  return result;
218 }
219 
220 //----------------------------------------------------------------------------//
221 
222 bool
223 SparseFieldIO::write(hid_t layerGroup, FieldBase::Ptr field)
224 {
225  if (layerGroup == -1) {
226  Msg::print(Msg::SevWarning, "Bad layerGroup.");
227  return false;
228  }
229 
230  // Add version attribute
231  if (!writeAttribute(layerGroup, k_versionAttrName,
232  1, k_versionNumber)) {
233  Msg::print(Msg::SevWarning, "Error adding version attribute.");
234  return false;
235  }
236 
237  SparseField<half>::Ptr halfField =
239  SparseField<float>::Ptr floatField =
241  SparseField<double>::Ptr doubleField =
243  SparseField<V3h>::Ptr vecHalfField =
245  SparseField<V3f>::Ptr vecFloatField =
247  SparseField<V3d>::Ptr vecDoubleField =
249 
250  bool success = true;
251  if (halfField) {
252  success = writeInternal<half>(layerGroup, halfField);
253  } else if (floatField) {
254  success = writeInternal<float>(layerGroup, floatField);
255  } else if (doubleField) {
256  success = writeInternal<double>(layerGroup, doubleField);
257  } else if (vecHalfField) {
258  success = writeInternal<V3h>(layerGroup, vecHalfField);
259  } else if (vecFloatField) {
260  success = writeInternal<V3f>(layerGroup, vecFloatField);
261  } else if (vecDoubleField) {
262  success = writeInternal<V3d>(layerGroup, vecDoubleField);
263  } else {
264  throw WriteLayerException("SparseFieldIO::write does not support the given "
265  "SparseField template parameter");
266  }
267 
268  return success;
269 }
270 
271 //----------------------------------------------------------------------------//
272 
274 
275 //----------------------------------------------------------------------------//
Field_T::Ptr field_dynamic_cast(RefBase::Ptr field)
Dynamic cast that uses string-comparison in order to be safe even after an object crosses a shared li...
Definition: RefCount.h:256
Imath::Box3i Box3i
Definition: SpiMathLib.h:77
Contains utility functions and classes for Hdf5 files.
Definition: Hdf5Util.h:86
Contains typedefs for the commonly used types in Field3D.
FIELD3D_API bool writeAttribute(hid_t location, const std::string &attrName, const std::string &value)
Writes a string attribute.
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition: ns.h:60
Namespace for Exception objects.
Definition: Exception.h:57
static const std::string k_dataStr
static const std::string k_versionAttrName
virtual bool write(hid_t layerGroup, FieldBase::Ptr field)
Writes the given field to disk.
static const std::string k_dataWindowStr
FIELD3D_API bool readAttribute(hid_t location, const std::string &attrName, std::string &value)
Reads a string attribute.
boost::intrusive_ptr< FieldBase > Ptr
Definition: Field.h:97
static const std::string k_numOccupiedBlocksStr
static const std::string k_extentsStr
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity. ...
Definition: Log.cpp:66
boost::intrusive_ptr< SparseField > Ptr
Definition: SparseField.h:357
static const int k_versionNumber
Imath::V3i V3i
Definition: SpiMathLib.h:71
void setSize(const V3i &size)
Resizes the object.
Definition: Field.h:918
virtual FieldBase::Ptr read(hid_t layerGroup, const std::string &filename, const std::string &layerPath, DataTypeEnum typeEnum)
Reads the field at the given location and tries to create a SparseField object from it...
static const std::string k_blockOrderStr
static const std::string k_numBlocksStr
static const std::string k_componentsStr
static const std::string k_blockResStr
void setBlockOrder(int order)
Sets the block order (i.e. the power-of-2 to use as block size.
Definition: SparseField.h:1436
Contains the SparseFieldIO class.
static const std::string k_bitsPerComponentStr
This Field subclass stores voxel data in block-allocated arrays.
Definition: SparseField.h:350
DataTypeEnum
Definition: Traits.h:66