Field3D
FieldMappingIO.cpp
Go to the documentation of this file.
00001 //----------------------------------------------------------------------------//
00002 
00003 /*
00004  * Copyright (c) 2009 Sony Pictures Imageworks Inc
00005  *
00006  * All rights reserved.
00007  *
00008  * Redistribution and use in source and binary forms, with or without
00009  * modification, are permitted provided that the following conditions
00010  * are met:
00011  *
00012  * Redistributions of source code must retain the above copyright
00013  * notice, this list of conditions and the following disclaimer.
00014  * Redistributions in binary form must reproduce the above copyright
00015  * notice, this list of conditions and the following disclaimer in the
00016  * documentation and/or other materials provided with the
00017  * distribution.  Neither the name of Sony Pictures Imageworks nor the
00018  * names of its contributors may be used to endorse or promote
00019  * products derived from this software without specific prior written
00020  * permission.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
00023  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
00024  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
00025  * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
00026  * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
00027  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
00028  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
00029  * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
00030  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
00031  * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
00032  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
00033  * OF THE POSSIBILITY OF SUCH DAMAGE.
00034  */
00035 
00036 //----------------------------------------------------------------------------//
00037 
00043 //----------------------------------------------------------------------------//
00044 
00045 #include "Hdf5Util.h"
00046 
00047 #include "FieldMappingIO.h"
00048 
00049 //----------------------------------------------------------------------------//
00050 
00051 FIELD3D_NAMESPACE_OPEN
00052 
00053 //----------------------------------------------------------------------------//
00054 // Field3D namespaces
00055 //----------------------------------------------------------------------------//
00056 
00057 using namespace std;
00058 using namespace Exc;
00059 using namespace Hdf5Util;
00060 
00061 //----------------------------------------------------------------------------//
00062 
00063 namespace {
00065   const string k_nullMappingName("NullFieldMapping");
00067   const string k_matrixMappingName("MatrixFieldMapping");
00068   const string k_frustumMappingName("FrustumFieldMapping");
00069 
00070   const string k_nullMappingDataName("NullFieldMapping data");
00071   
00072   const string k_matrixMappingDataName("MatrixFieldMapping data");
00073   const string k_matrixMappingNumSamples("num_time_samples");
00074   const string k_matrixMappingTime("time_");
00075   const string k_matrixMappingMatrix("matrix_");
00076 
00077   const string k_frustumMappingNumSamples("num_time_samples");
00078   const string k_frustumMappingTime("time_");
00079   const string k_frustumMappingScreenMatrix("screen_to_world_");
00080   const string k_frustumMappingCameraMatrix("camera_to_world_");
00081   const string k_frustumMappingZDistribution("z_distribution");
00082 }
00083 
00084 //----------------------------------------------------------------------------//
00085 
00086 FieldMapping::Ptr
00087 NullFieldMappingIO::read(hid_t mappingGroup)
00088 {
00089   string nfmData;
00090   if (!readAttribute(mappingGroup, k_nullMappingDataName, nfmData)) {
00091     Msg::print(Msg::SevWarning, "Couldn't read attribute " + k_nullMappingDataName);
00092     return NullFieldMapping::Ptr();
00093   }
00094   return NullFieldMapping::Ptr(new NullFieldMapping);
00095 }
00096 
00097 //----------------------------------------------------------------------------//
00098 
00099 bool
00100 NullFieldMappingIO::write(hid_t mappingGroup, FieldMapping::Ptr /* nm */)
00101 {
00102   string nfmAttrData("NullFieldMapping has no data");
00103   if (!writeAttribute(mappingGroup, k_nullMappingDataName, nfmAttrData)) {
00104     Msg::print(Msg::SevWarning, "Couldn't add attribute " + k_nullMappingDataName);
00105     return false;
00106   }
00107   return true;
00108 }
00109 
00110 //----------------------------------------------------------------------------//
00111 
00112 std::string NullFieldMappingIO::className() const
00113 { 
00114   return k_nullMappingName; 
00115 }
00116 
00117 //----------------------------------------------------------------------------//
00118 // MatrixFieldMapping
00119 //----------------------------------------------------------------------------//
00120 
00121 FieldMapping::Ptr
00122 MatrixFieldMappingIO::read(hid_t mappingGroup)
00123 {
00124   M44d mtx;
00125   int numSamples=0;
00126 
00127   MatrixFieldMapping::Ptr mm(new MatrixFieldMapping);
00128   
00129   // For backward compatibility, we first try to read the non-time-varying
00130   // mapping.
00131 
00132   try {
00133     readAttribute(mappingGroup, k_matrixMappingDataName, 16, mtx.x[0][0]);
00134     mm->setLocalToWorld(mtx);
00135     return mm;
00136   } 
00137   catch (...) {
00138     // Do nothing
00139   }
00140 
00141   // If we didn't find the non-time-varying matrix data then we attempt
00142   // to read time samples
00143 
00144   try {
00145     if (!readAttribute(mappingGroup, k_matrixMappingNumSamples, 1, numSamples)) {
00146       Msg::print(Msg::SevWarning, "Couldn't read attribute " + 
00147                  k_matrixMappingNumSamples);
00148       return FieldMapping::Ptr();
00149     }
00150   } catch (...) {
00151     //do nothing
00152   }
00153 
00154   for (int i = 0; i < numSamples; ++i) {
00155     float time;
00156     string timeAttr = k_matrixMappingTime + boost::lexical_cast<string>(i);
00157     string matrixAttr = k_matrixMappingMatrix + boost::lexical_cast<string>(i);
00158     if (!readAttribute(mappingGroup, timeAttr, 1, time)) {
00159       Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
00160       return FieldMapping::Ptr();
00161     }
00162     std::vector<unsigned int> attrSize;
00163     attrSize.assign(2,4);
00164 
00165     if (!readAttribute(mappingGroup, matrixAttr, attrSize, mtx.x[0][0])) {
00166       Msg::print(Msg::SevWarning, "Couldn't read attribute " + matrixAttr);
00167       return FieldMapping::Ptr();
00168     }
00169     mm->setLocalToWorld(time, mtx);
00170   }
00171   
00172   return mm;
00173 }
00174 
00175 //----------------------------------------------------------------------------//
00176 
00177 bool
00178 MatrixFieldMappingIO::write(hid_t mappingGroup, FieldMapping::Ptr mapping)
00179 {
00180   typedef MatrixFieldMapping::MatrixCurve::SampleVec SampleVec;
00181 
00182   MatrixFieldMapping::Ptr mm =
00183     FIELD_DYNAMIC_CAST<MatrixFieldMapping>(mapping);
00184 
00185   if (!mm) {
00186     Msg::print(Msg::SevWarning, "Couldn't get MatrixFieldMapping from pointer");
00187     return false;
00188   }
00189 
00190   // First write number of time samples
00191 
00192   const SampleVec &samples = mm->localToWorldSamples();
00193   int numSamples = static_cast<int>(samples.size());
00194 
00195   if (!writeAttribute(mappingGroup, k_matrixMappingNumSamples, 1, numSamples)) {
00196     Msg::print(Msg::SevWarning, "Couldn't add attribute " + 
00197                k_matrixMappingNumSamples);
00198     return false;
00199   }
00200 
00201   // Then write each sample
00202 
00203   for (int i = 0; i < numSamples; ++i) {
00204     string timeAttr = k_matrixMappingTime + boost::lexical_cast<string>(i);
00205     string matrixAttr = k_matrixMappingMatrix + boost::lexical_cast<string>(i);
00206     if (!writeAttribute(mappingGroup, timeAttr, 1, samples[i].first)) {
00207       Msg::print(Msg::SevWarning, "Couldn't add attribute " + timeAttr);
00208       return false;
00209     }
00210     std::vector<unsigned int> attrSize;
00211     attrSize.assign(2,4);
00212     if (!writeAttribute(mappingGroup, matrixAttr, attrSize, 
00213                         samples[i].second.x[0][0])) {
00214       Msg::print(Msg::SevWarning, "Couldn't add attribute " + matrixAttr);
00215       return false;
00216     }
00217   }
00218 
00219   return true;
00220 }
00221 
00222 //----------------------------------------------------------------------------//
00223 
00224 std::string MatrixFieldMappingIO::className() const
00225 { 
00226   return k_matrixMappingName;
00227 }
00228 
00229 //----------------------------------------------------------------------------//
00230 // FrustumFieldMapping
00231 //----------------------------------------------------------------------------//
00232 
00233 FieldMapping::Ptr
00234 FrustumFieldMappingIO::read(hid_t mappingGroup)
00235 {
00236   float time;
00237   M44d ssMtx, csMtx;
00238   int numSamples=0;
00239 
00240   FrustumFieldMapping::Ptr fm(new FrustumFieldMapping);
00241   
00242   // Read number of time samples
00243 
00244   try {
00245     if (!readAttribute(mappingGroup, k_frustumMappingNumSamples, 1, numSamples)) {
00246       Msg::print(Msg::SevWarning, "Couldn't read attribute " + 
00247                  k_frustumMappingNumSamples);
00248       return FieldMapping::Ptr();
00249     }
00250   } catch (...) {
00251     //do nothing
00252   }
00253 
00254   // Read each time sample
00255 
00256   for (int i = 0; i < numSamples; ++i) {
00257     string timeAttr = k_frustumMappingTime + boost::lexical_cast<string>(i);
00258     string ssAttr = k_frustumMappingScreenMatrix + boost::lexical_cast<string>(i);
00259     string csAttr = k_frustumMappingCameraMatrix + boost::lexical_cast<string>(i);
00260     if (!readAttribute(mappingGroup, timeAttr, 1, time)) {
00261       Msg::print(Msg::SevWarning, "Couldn't read attribute " + timeAttr);
00262       return FieldMapping::Ptr();
00263     }
00264     std::vector<unsigned int> attrSize;
00265     attrSize.assign(2,4);
00266 
00267     if (!readAttribute(mappingGroup, ssAttr, attrSize, ssMtx.x[0][0])) {
00268       Msg::print(Msg::SevWarning, "Couldn't read attribute " + ssAttr);
00269       return FieldMapping::Ptr();
00270     }
00271     if (!readAttribute(mappingGroup, csAttr, attrSize, csMtx.x[0][0])) {
00272       Msg::print(Msg::SevWarning, "Couldn't read attribute " + csAttr);
00273       return FieldMapping::Ptr();
00274     }
00275 
00276     fm->setTransforms(time, ssMtx, csMtx);
00277   }
00278 
00279 
00280   // Read Z distribution
00281 
00282   int distInt;
00283   FrustumFieldMapping::ZDistribution dist;
00284   
00285   try {
00286     if (!readAttribute(mappingGroup, k_frustumMappingZDistribution, 1, distInt)) {
00287       Msg::print(Msg::SevWarning, "Couldn't read attribute " + 
00288                  k_frustumMappingZDistribution);
00289       return FieldMapping::Ptr();
00290     }
00291     dist = static_cast<FrustumFieldMapping::ZDistribution>(distInt); 
00292   } catch (...) {
00293     dist = FrustumFieldMapping::PerspectiveDistribution;
00294   }
00295 
00296   fm->setZDistribution(dist);
00297 
00298   return fm;
00299 }
00300 
00301 //----------------------------------------------------------------------------//
00302 
00303 bool
00304 FrustumFieldMappingIO::write(hid_t mappingGroup, FieldMapping::Ptr mapping)
00305 {
00306   typedef FrustumFieldMapping::MatrixCurve::SampleVec SampleVec;
00307 
00308   FrustumFieldMapping::Ptr fm =
00309     FIELD_DYNAMIC_CAST<FrustumFieldMapping>(mapping);
00310 
00311   if (!fm) {
00312     Msg::print(Msg::SevWarning, "Couldn't get FrustumFieldMapping from pointer");
00313     return false;
00314   }
00315 
00316   // First write number of time samples
00317 
00318   const SampleVec &ssSamples = fm->screenToWorldSamples();
00319   const SampleVec &csSamples = fm->cameraToWorldSamples();
00320   int numSamples = static_cast<int>(ssSamples.size());
00321 
00322   if (!writeAttribute(mappingGroup, k_frustumMappingNumSamples, 1, numSamples)) {
00323     Msg::print(Msg::SevWarning, "Couldn't add attribute " + 
00324                k_frustumMappingNumSamples);
00325     return false;
00326   }
00327 
00328   // Then write each sample
00329 
00330   for (int i = 0; i < numSamples; ++i) {
00331     string timeAttr = k_frustumMappingTime + boost::lexical_cast<string>(i);
00332     string ssAttr = k_frustumMappingScreenMatrix + boost::lexical_cast<string>(i);
00333     string csAttr = k_frustumMappingCameraMatrix + boost::lexical_cast<string>(i);
00334     if (!writeAttribute(mappingGroup, timeAttr, 1, ssSamples[i].first)) {
00335       Msg::print(Msg::SevWarning, "Couldn't add attribute " + timeAttr);
00336       return false;
00337     }
00338 
00339     std::vector<unsigned int> attrSize;
00340     attrSize.assign(2,4);
00341 
00342     if (!writeAttribute(mappingGroup, ssAttr,attrSize,
00343                         ssSamples[i].second.x[0][0])) {
00344       Msg::print(Msg::SevWarning, "Couldn't add attribute " + ssAttr);
00345       return false;
00346     }
00347     if (!writeAttribute(mappingGroup, csAttr, attrSize,
00348                         csSamples[i].second.x[0][0])) {
00349       Msg::print(Msg::SevWarning, "Couldn't add attribute " + csAttr);
00350       return false;
00351     }
00352   }
00353 
00354   // Write distribution type
00355 
00356   int dist = static_cast<int>(fm->zDistribution());
00357 
00358   if (!writeAttribute(mappingGroup, k_frustumMappingZDistribution, 1, dist)) {
00359     Msg::print(Msg::SevWarning, "Couldn't add attribute " + 
00360                k_frustumMappingNumSamples);
00361     return false;
00362   }
00363 
00364   return true;
00365 }
00366 
00367 //----------------------------------------------------------------------------//
00368 
00369 std::string FrustumFieldMappingIO::className() const
00370 { 
00371   return k_frustumMappingName;
00372 }
00373 
00374 //----------------------------------------------------------------------------//
00375 
00376 FIELD3D_NAMESPACE_SOURCE_CLOSE
00377 
00378 //----------------------------------------------------------------------------//