Field3D
|
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 00045 //----------------------------------------------------------------------------// 00046 00047 #ifndef _INCLUDED_Field3D_Field3DFile_H_ 00048 #define _INCLUDED_Field3D_Field3DFile_H_ 00049 00050 //----------------------------------------------------------------------------// 00051 00052 #include <list> 00053 #include <string> 00054 #include <vector> 00055 00056 #include <hdf5.h> 00057 00058 #include <boost/intrusive_ptr.hpp> 00059 00060 #include "EmptyField.h" 00061 #include "Field.h" 00062 #include "FieldMetadata.h" 00063 #include "ClassFactory.h" 00064 #include "Hdf5Util.h" 00065 00066 //----------------------------------------------------------------------------// 00067 00068 #include "ns.h" 00069 00070 FIELD3D_NAMESPACE_OPEN 00071 00072 00073 00074 //----------------------------------------------------------------------------// 00075 // Function Declarations 00076 //----------------------------------------------------------------------------// 00077 00079 // \{ 00080 00083 template <class Data_T> 00084 typename Field<Data_T>::Ptr 00085 readField(const std::string &className, hid_t layerGroup, 00086 const std::string &filename, const std::string &layerPath); 00089 bool writeField(hid_t layerGroup, FieldBase::Ptr field); 00090 00093 FieldMapping::Ptr readFieldMapping(hid_t mappingGroup); 00094 00098 bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping); 00099 00101 00102 //----------------------------------------------------------------------------// 00103 // Layer 00104 //----------------------------------------------------------------------------// 00105 00108 namespace File { 00109 00117 class Layer 00118 { 00119 public: 00121 std::string name; 00124 std::string parent; 00125 }; 00126 00127 } // namespace File 00128 00129 //----------------------------------------------------------------------------// 00130 // Partition 00131 //----------------------------------------------------------------------------// 00132 00133 namespace File { 00134 00142 class Partition : public RefBase 00143 { 00144 public: 00145 00146 typedef std::vector<Layer> ScalarLayerList; 00147 typedef std::vector<Layer> VectorLayerList; 00148 00149 typedef boost::intrusive_ptr<Partition> Ptr; 00150 typedef boost::intrusive_ptr<const Partition> CPtr; 00151 00152 // RTTI replacement ---------------------------------------------------------- 00153 00154 typedef Partition class_type; 00155 DEFINE_FIELD_RTTI_CONCRETE_CLASS; 00156 00157 static const char *classType() 00158 { 00159 return "Partition"; 00160 } 00161 00162 // Ctors, dtor --------------------------------------------------------------- 00163 00165 Partition() 00166 : RefBase() 00167 { } 00168 00169 // From RefBase -------------------------------------------------------------- 00170 00173 00174 virtual std::string className() const; 00175 00177 00178 // Main methods -------------------------------------------------------------- 00179 00181 void addScalarLayer(const File::Layer &layer); 00183 void addVectorLayer(const File::Layer &layer); 00184 00186 const File::Layer* scalarLayer(const std::string &name) const; 00188 const File::Layer* vectorLayer(const std::string &name) const; 00189 00191 void getScalarLayerNames(std::vector<std::string> &names) const; 00193 void getVectorLayerNames(std::vector<std::string> &names) const; 00194 00195 // Public data members ------------------------------------------------------- 00196 00198 std::string name; 00200 FieldMapping::Ptr mapping; 00201 00202 private: 00203 00204 // Private data members ------------------------------------------------------ 00205 00207 ScalarLayerList m_scalarLayers; 00209 VectorLayerList m_vectorLayers; 00210 00211 // Typedefs ------------------------------------------------------------------ 00212 00214 typedef RefBase base; 00215 00216 }; 00217 00218 } // namespace File 00219 00220 //----------------------------------------------------------------------------// 00221 // Field3DFileBase 00222 //----------------------------------------------------------------------------// 00223 00231 //----------------------------------------------------------------------------// 00232 00233 class Field3DFileBase 00234 { 00235 public: 00236 00237 // Structs ------------------------------------------------------------------- 00238 00239 struct LayerInfo 00240 { 00241 std::string name; 00242 std::string parentName; 00243 int components; 00244 LayerInfo(std::string par, std::string nm, int cpt) 00245 : name(nm), parentName(par), components(cpt) 00246 { /* Empty */ } 00247 }; 00248 00249 // Typedefs ------------------------------------------------------------------ 00250 00251 typedef std::map<std::string, std::string> GroupMembershipMap; 00252 00253 // Ctor, dtor ---------------------------------------------------------------- 00254 00257 00258 Field3DFileBase(); 00260 virtual ~Field3DFileBase() = 0; 00261 00263 00264 // Main methods -------------------------------------------------------------- 00265 00267 void clear(); 00268 00272 bool close(); 00273 00276 00278 void getPartitionNames(std::vector<std::string> &names) const; 00280 void getScalarLayerNames(std::vector<std::string> &names, 00281 const std::string &partitionName) const; 00283 void getVectorLayerNames(std::vector<std::string> &names, 00284 const std::string &partitionName) const; 00285 00288 File::Partition::Ptr getPartition(const std::string &partitionName) const 00289 { return partition(partitionName); } 00290 00292 00295 00299 std::string intPartitionName(const std::string &partitionName, 00300 const std::string &layerName, 00301 FieldRes::Ptr field); 00302 00305 std::string removeUniqueId(const std::string &partitionName) const; 00306 00308 void addGroupMembership(const GroupMembershipMap &groupMembers); 00309 00311 00312 // Access to metadata -------------------------------------------------------- 00313 00315 FieldMetadata<Field3DFileBase>& metadata() 00316 { return m_metadata; } 00317 00319 const FieldMetadata<Field3DFileBase>& metadata() const 00320 { return m_metadata; } 00321 00324 virtual void metadataHasChanged(const std::string &/* name */) 00325 { /* Empty */ } 00326 00327 // Debug --------------------------------------------------------------------- 00328 00331 00332 void printHierarchy() const; 00333 00335 00336 protected: 00337 00338 // Internal typedefs --------------------------------------------------------- 00339 00340 typedef std::vector<File::Partition::Ptr> PartitionList; 00341 typedef std::map<std::string, int> PartitionCountMap; 00342 00343 // Convenience methods ------------------------------------------------------- 00344 00347 00349 void closeInternal(); 00352 File::Partition::Ptr partition(const std::string &partitionName); 00355 File::Partition::Ptr partition(const std::string &partitionName) const; 00356 00358 void getIntPartitionNames(std::vector<std::string> &names) const; 00361 void getIntScalarLayerNames(std::vector<std::string> &names, 00362 const std::string &intPartitionName) const; 00365 void getIntVectorLayerNames(std::vector<std::string> &names, 00366 const std::string &intPartitionName) const; 00367 00369 int numIntPartitions(const std::string &partitionName) const; 00370 00373 std::string makeIntPartitionName(const std::string &partitionsName, 00374 int i) const; 00375 00377 00378 // Data members -------------------------------------------------------------- 00379 00381 std::vector<LayerInfo> m_layerInfo; 00382 00384 hid_t m_file; 00386 PartitionList m_partitions; 00388 std::vector<std::string> m_partitionNames; 00389 00392 PartitionCountMap m_partitionCount; 00393 00397 GroupMembershipMap m_groupMembership; 00398 00400 FieldMetadata<Field3DFileBase> m_metadata; 00401 00402 private: 00403 00404 // Private member functions -------------------------------------------------- 00405 00406 Field3DFileBase(const Field3DFileBase&); 00407 void operator =(const Field3DFileBase&); 00408 00409 00410 }; 00411 00412 //----------------------------------------------------------------------------// 00413 // Field3DInputFile 00414 //----------------------------------------------------------------------------// 00415 00429 //----------------------------------------------------------------------------// 00430 00431 class Field3DInputFile : public Field3DFileBase 00432 { 00433 public: 00434 00435 // Ctors, dtor --------------------------------------------------------------- 00436 00439 00440 Field3DInputFile(); 00441 virtual ~Field3DInputFile(); 00442 00444 00445 // Main interface ------------------------------------------------------------ 00446 00449 00454 template <class Data_T> 00455 typename Field<Data_T>::Vec 00456 readScalarLayers(const std::string &layerName = std::string("")) const; 00457 00459 template <class Data_T> 00460 typename Field<Data_T>::Vec 00461 readScalarLayers(const std::string &partitionName, 00462 const std::string &layerName) const; 00463 00468 template <class Data_T> 00469 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00470 readVectorLayers(const std::string &layerName = std::string("")) const; 00471 00473 template <class Data_T> 00474 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00475 readVectorLayers(const std::string &partitionName, 00476 const std::string &layerName) const; 00477 00480 template <template <typename T> class Field_T, class Data_T> 00481 typename Field_T<Data_T>::Vec 00482 readScalarLayersAs(const std::string &layerName = std::string("")) const; 00483 00486 template <template <typename T> class Field_T, class Data_T> 00487 typename Field_T<Data_T>::Vec 00488 readScalarLayersAs(const std::string &partitionName, 00489 const std::string &layerName) const; 00490 00493 template <template <typename T> class Field_T, class Data_T> 00494 typename Field_T<Data_T>::Vec 00495 readVectorLayersAs(const std::string &layerName = std::string("")) const; 00496 00499 template <template <typename T> class Field_T, class Data_T> 00500 typename Field_T<Data_T>::Vec 00501 readVectorLayersAs(const std::string &partitionName, 00502 const std::string &layerName) const; 00503 00505 00508 00514 template <class Data_T> 00515 typename EmptyField<Data_T>::Vec 00516 readProxyLayer(const std::string &partitionName, 00517 const std::string &layerName, 00518 bool isVectorLayer) const; 00519 00525 template <class Data_T> 00526 typename EmptyField<Data_T>::Vec 00527 readProxyScalarLayers(const std::string &name = std::string("")) const; 00528 00534 template <class Data_T> 00535 typename EmptyField<Data_T>::Vec 00536 readProxyVectorLayers(const std::string &name = std::string("")) const; 00537 00539 00540 // File IO --- 00541 00544 bool open(const std::string &filename); 00545 00546 // Callback convenience methods ---------------------------------------------- 00547 00550 00552 herr_t parsePartition(hid_t loc_id, const std::string partitionName); 00553 00555 herr_t parseLayer(hid_t loc_id, const std::string &partitionName, 00556 const std::string &layerName); 00557 00559 00560 // Convenience methods ------------------------------------------------------- 00561 00563 bool readGroupMembership(GroupMembershipMap &gpMembershipMap); 00564 00565 private: 00566 00567 // Convenience methods ------------------------------------------------------- 00568 00571 template <class Data_T> 00572 typename Field<Data_T>::Ptr 00573 readScalarLayer(const std::string &intPartitionName, 00574 const std::string &layerName) const; 00575 00578 template <class Data_T> 00579 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr 00580 readVectorLayer(const std::string &intPartitionName, 00581 const std::string &layerName) const; 00582 00585 template <class Data_T> 00586 typename Field<Data_T>::Ptr 00587 readLayer(const std::string &intPartitionName, 00588 const std::string &layerName, 00589 bool isVectorLayer) const; 00590 00592 bool readPartitionAndLayerInfo(); 00593 00595 bool readMetadata(hid_t metadata_id, FieldBase::Ptr field) const; 00596 00598 bool readMetadata(hid_t metadata_id); 00599 00600 // Data members -------------------------------------------------------------- 00601 00603 std::string m_filename; 00604 00605 }; 00606 00607 //----------------------------------------------------------------------------// 00608 // Field3DOutputFile 00609 //----------------------------------------------------------------------------// 00610 00624 //----------------------------------------------------------------------------// 00625 00626 class Field3DOutputFile : public Field3DFileBase 00627 { 00628 public: 00629 00630 // Enums --------------------------------------------------------------------- 00631 00632 enum CreateMode { 00633 OverwriteMode, 00634 FailOnExisting 00635 }; 00636 00637 // Ctors, dtor --------------------------------------------------------------- 00638 00641 00642 Field3DOutputFile(); 00643 virtual ~Field3DOutputFile(); 00644 00646 00647 // Main interface ------------------------------------------------------------ 00648 00651 00653 template <class Data_T> 00654 bool writeScalarLayer(const std::string &layerName, 00655 typename Field<Data_T>::Ptr layer) 00656 { return writeScalarLayer<Data_T>(layerName, std::string("default"), layer); } 00657 00659 template <class Data_T> 00660 bool writeVectorLayer(const std::string &layerName, 00661 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer) 00662 { return writeVectorLayer<Data_T>(layerName, std::string("default"), layer); } 00663 00666 template <class Data_T> 00667 bool writeScalarLayer(const std::string &partitionName, 00668 const std::string &layerName, 00669 typename Field<Data_T>::Ptr layer); 00670 00673 template <class Data_T> 00674 bool writeScalarLayer(typename Field<Data_T>::Ptr layer); 00675 00678 template <class Data_T> 00679 bool writeVectorLayer(const std::string &partitionName, 00680 const std::string &layerName, 00681 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer); 00682 00685 template <class Data_T> 00686 bool writeVectorLayer(typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer); 00687 00689 00691 bool create(const std::string &filename, CreateMode cm = OverwriteMode); 00692 00694 bool writeGlobalMetadata(); 00695 00698 bool writeGroupMembership(); 00699 00701 std::string incrementPartitionName(std::string &pname); 00702 00704 template <class Data_T> 00705 File::Partition::Ptr 00706 createNewPartition(const std::string &partitionName, 00707 const std::string &layerName, 00708 typename Field<Data_T>::Ptr field); 00709 private: 00710 00711 // Convenience methods ------------------------------------------------------- 00712 00716 bool writeMapping(hid_t partitionLocation, FieldMapping::Ptr mapping); 00717 00719 template <class Data_T> 00720 bool writeLayer(const std::string &partitionName, 00721 const std::string &layerName, 00722 bool isVectorLayer, 00723 typename Field<Data_T>::Ptr layer); 00724 00726 bool writeMetadata(hid_t metadataGroup, FieldBase::Ptr layer); 00727 00729 bool writeMetadata(hid_t metadataGroup); 00730 00731 }; 00732 00733 //----------------------------------------------------------------------------// 00734 // Field3DInputFile-related callback functions 00735 //----------------------------------------------------------------------------// 00736 00738 namespace InputFile { 00739 00743 struct ParseLayersInfo 00744 { 00745 Field3DInputFile *file; 00746 std::string partitionName; 00747 }; 00748 00752 herr_t parsePartitions(hid_t loc_id, const char *partitionName, 00753 const H5L_info_t *linfo, void *opdata); 00754 00758 herr_t parseLayers(hid_t loc_id, const char *partitionName, 00759 const H5L_info_t *linfo, void *opdata); 00760 00761 } // namespace InputFile 00762 00763 //----------------------------------------------------------------------------// 00764 // Field3DInputFile 00765 //----------------------------------------------------------------------------// 00766 00767 template <class Data_T> 00768 typename Field<Data_T>::Vec 00769 Field3DInputFile::readScalarLayers(const std::string &name) const 00770 { 00771 using namespace std; 00772 00773 typedef typename Field<Data_T>::Ptr FieldPtr; 00774 typedef typename Field<Data_T>::Vec FieldList; 00775 00776 FieldList ret; 00777 std::vector<std::string> parts; 00778 getIntPartitionNames(parts); 00779 00780 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00781 std::vector<std::string> layers; 00782 getIntScalarLayerNames(layers, *p); 00783 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 00784 // Only read if it matches the name 00785 if ((name.length() == 0) || (*l == name)) { 00786 FieldPtr mf = readScalarLayer<Data_T>(*p, *l); 00787 if (mf) { 00788 ret.push_back(mf); 00789 } 00790 } 00791 } 00792 } 00793 00794 return ret; 00795 } 00796 00797 //----------------------------------------------------------------------------// 00798 00799 template <class Data_T> 00800 typename Field<Data_T>::Vec 00801 Field3DInputFile::readScalarLayers(const std::string &partitionName, 00802 const std::string &layerName) const 00803 { 00804 using namespace std; 00805 00806 typedef typename Field<Data_T>::Ptr FieldPtr; 00807 typedef typename Field<Data_T>::Vec FieldList; 00808 00809 FieldList ret; 00810 00811 if ((layerName.length() == 0) || (partitionName.length() == 0)) 00812 return ret; 00813 00814 std::vector<std::string> parts; 00815 getIntPartitionNames(parts); 00816 00817 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00818 std::vector<std::string> layers; 00819 getIntScalarLayerNames(layers, *p); 00820 if (removeUniqueId(*p) == partitionName) { 00821 for (vector<string>::iterator l = layers.begin(); 00822 l != layers.end(); ++l) { 00823 // Only read if it matches the name 00824 if (*l == layerName) { 00825 FieldPtr mf = readScalarLayer<Data_T>(*p, *l); 00826 if (mf) 00827 ret.push_back(mf); 00828 } 00829 } 00830 } 00831 } 00832 00833 return ret; 00834 } 00835 00836 //----------------------------------------------------------------------------// 00837 00838 template <class Data_T> 00839 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00840 Field3DInputFile::readVectorLayers(const std::string &name) const 00841 { 00842 using namespace std; 00843 00844 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr; 00845 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList; 00846 00847 FieldList ret; 00848 00849 std::vector<std::string> parts; 00850 getIntPartitionNames(parts); 00851 00852 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00853 std::vector<std::string> layers; 00854 getIntVectorLayerNames(layers, *p); 00855 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 00856 // Only read if it matches the name 00857 if ((name.length() == 0) || (*l == name)) { 00858 FieldPtr mf = readVectorLayer<Data_T>(*p, *l); 00859 if (mf) 00860 ret.push_back(mf); 00861 } 00862 } 00863 } 00864 00865 return ret; 00866 } 00867 00868 //----------------------------------------------------------------------------// 00869 00870 template <class Data_T> 00871 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00872 Field3DInputFile::readVectorLayers(const std::string &partitionName, 00873 const std::string &layerName) const 00874 { 00875 using namespace std; 00876 00877 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr; 00878 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList; 00879 00880 FieldList ret; 00881 00882 if ((layerName.length() == 0) || (partitionName.length() == 0)) 00883 return ret; 00884 00885 std::vector<std::string> parts; 00886 getIntPartitionNames(parts); 00887 00888 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00889 std::vector<std::string> layers; 00890 getIntVectorLayerNames(layers, *p); 00891 if (removeUniqueId(*p) == partitionName) { 00892 for (vector<string>::iterator l = layers.begin(); 00893 l != layers.end(); ++l) { 00894 // Only read if it matches the name 00895 if (*l == layerName) { 00896 FieldPtr mf = readVectorLayer<Data_T>(*p, *l); 00897 if (mf) 00898 ret.push_back(mf); 00899 } 00900 } 00901 } 00902 } 00903 00904 return ret; 00905 } 00906 00907 //----------------------------------------------------------------------------// 00908 00909 template <class Data_T> 00910 typename Field<Data_T>::Ptr 00911 Field3DInputFile::readLayer(const std::string &intPartitionName, 00912 const std::string &layerName, 00913 bool isVectorLayer) const 00914 { 00915 using namespace boost; 00916 using namespace std; 00917 using namespace Hdf5Util; 00918 00919 // Instantiate a null pointer for easier code reading 00920 typename Field<Data_T>::Ptr nullPtr; 00921 00922 // Find the partition 00923 File::Partition::Ptr part = partition(intPartitionName); 00924 if (!part) { 00925 Msg::print(Msg::SevWarning, "Couldn't find partition: " + intPartitionName); 00926 return nullPtr; 00927 } 00928 00929 // Find the layer in the partition 00930 const File::Layer *l; 00931 if (isVectorLayer) 00932 l = part->vectorLayer(layerName); 00933 else 00934 l = part->scalarLayer(layerName); 00935 if (!l) { 00936 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName ); 00937 return nullPtr; 00938 } 00939 00940 // Open the layer group 00941 string layerPath = l->parent + "/" + l->name; 00942 H5ScopedGopen layerGroup(m_file, layerPath.c_str()); 00943 00944 if (layerGroup.id() < 0) { 00945 Msg::print(Msg::SevWarning, "Couldn't find layer group " + layerName 00946 + " in .f3d file "); 00947 return nullPtr; 00948 } 00949 00950 // Get the class name 00951 string className; 00952 if (!readAttribute(layerGroup.id(), "class_name", className)) { 00953 Msg::print(Msg::SevWarning, "Couldn't find class_name attrib in layer " + 00954 layerName); 00955 return nullPtr; 00956 } 00957 00958 // Construct the field and load the data 00959 00960 typename Field<Data_T>::Ptr field; 00961 field = readField<Data_T>(className, layerGroup.id(), m_filename, layerPath); 00962 00963 if (!field) { 00964 #if 0 // This isn't really an error 00965 Msg::print(Msg::SevWarning, "Couldn't read the layer data of layer: " 00966 + layerName); 00967 #endif 00968 return nullPtr; 00969 } 00970 00971 // read the metadata 00972 string metadataPath = layerPath + "/metadata"; 00973 H5ScopedGopen metadataGroup(m_file, metadataPath.c_str()); 00974 if (metadataGroup.id() > 0) { 00975 readMetadata(metadataGroup.id(), field); 00976 } 00977 00978 // Set the name of the field so it's possible to re-create the file 00979 field->name = removeUniqueId(intPartitionName); 00980 field->attribute = layerName; 00981 field->setMapping(part->mapping); 00982 00983 return field; 00984 } 00985 00986 //----------------------------------------------------------------------------// 00987 00988 template <template <typename T> class Field_T, class Data_T> 00989 typename Field_T<Data_T>::Vec 00990 Field3DInputFile::readScalarLayersAs(const std::string &layerName) const 00991 { 00992 typedef typename Field<Data_T>::Vec FieldList; 00993 typedef typename Field_T<Data_T>::Vec TypedFieldList; 00994 00995 // First, read the layers as-is 00996 FieldList originals; 00997 originals = readScalarLayers<Data_T>(layerName); 00998 00999 // Loop over fields, converting if needed 01000 TypedFieldList output; 01001 typename FieldList::iterator i = originals.begin(); 01002 for (; i != originals.end(); ++i) { 01003 typename Field_T<Data_T>::Ptr targetField; 01004 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01005 if (targetField) { 01006 output.push_back(targetField); 01007 } else { 01008 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01009 newTarget->name = (*i)->name; 01010 newTarget->attribute = (*i)->attribute; 01011 newTarget->copyMetadata(*i); 01012 newTarget->copyFrom(*i); 01013 output.push_back(newTarget); 01014 } 01015 } 01016 01017 return output; 01018 } 01019 01020 //----------------------------------------------------------------------------// 01021 01022 template <template <typename T> class Field_T, class Data_T> 01023 typename Field_T<Data_T>::Vec 01024 Field3DInputFile::readScalarLayersAs(const std::string &partitionName, 01025 const std::string &layerName) const 01026 { 01027 typedef typename Field<Data_T>::Vec FieldList; 01028 typedef typename Field_T<Data_T>::Vec TypedFieldList; 01029 01030 // First, read the layers as-is 01031 FieldList originals; 01032 originals = readScalarLayers<Data_T>(partitionName, layerName); 01033 01034 // Loop over fields, converting if needed 01035 TypedFieldList output; 01036 typename FieldList::iterator i = originals.begin(); 01037 for (; i != originals.end(); ++i) { 01038 typename Field_T<Data_T>::Ptr targetField; 01039 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01040 if (targetField) { 01041 output.push_back(targetField); 01042 } else { 01043 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01044 newTarget->name = (*i)->name; 01045 newTarget->attribute = (*i)->attribute; 01046 newTarget->copyMetadata(**i); 01047 newTarget->copyFrom(*i); 01048 output.push_back(newTarget); 01049 } 01050 } 01051 01052 return output; 01053 } 01054 01055 //----------------------------------------------------------------------------// 01056 01057 template <template <typename T> class Field_T, class Data_T> 01058 typename Field_T<Data_T>::Vec 01059 Field3DInputFile::readVectorLayersAs(const std::string &layerName) const 01060 { 01061 typedef typename Field<Data_T>::Vec FieldList; 01062 typedef typename Field_T<Data_T>::Vec TypedFieldList; 01063 01064 // First, read the layers as-is 01065 FieldList originals; 01066 originals = readVectorLayers<Data_T>(layerName); 01067 01068 // Loop over fields, converting if needed 01069 TypedFieldList output; 01070 typename FieldList::iterator i = originals.begin(); 01071 for (; i != originals.end(); ++i) { 01072 typename Field_T<Data_T>::Ptr targetField; 01073 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01074 if (targetField) { 01075 output.push_back(targetField); 01076 } else { 01077 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01078 newTarget->name = (*i)->name; 01079 newTarget->attribute = (*i)->attribute; 01080 newTarget->copyMetadata(*i); 01081 newTarget->copyFrom(*i); 01082 output.push_back(newTarget); 01083 } 01084 } 01085 01086 return output; 01087 } 01088 01089 //----------------------------------------------------------------------------// 01090 01091 template <template <typename T> class Field_T, class Data_T> 01092 typename Field_T<Data_T>::Vec 01093 Field3DInputFile::readVectorLayersAs(const std::string &partitionName, 01094 const std::string &layerName) const 01095 { 01096 typedef typename Field<Data_T>::Vec FieldList; 01097 typedef typename Field_T<Data_T>::Vec TypedFieldList; 01098 01099 // First, read the layers as-is 01100 FieldList originals; 01101 originals = readVectorLayers<Data_T>(partitionName, layerName); 01102 01103 // Loop over fields, converting if needed 01104 TypedFieldList output; 01105 typename FieldList::iterator i = originals.begin(); 01106 for (; i != originals.end(); ++i) { 01107 typename Field_T<Data_T>::Ptr targetField; 01108 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01109 if (targetField) { 01110 output.push_back(targetField); 01111 } else { 01112 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01113 newTarget->name = (*i)->name; 01114 newTarget->attribute = (*i)->attribute; 01115 newTarget->copyMetadata(*i); 01116 newTarget->copyFrom(*i); 01117 output.push_back(newTarget); 01118 } 01119 } 01120 01121 return output; 01122 } 01123 01124 //----------------------------------------------------------------------------// 01125 01126 template <class Data_T> 01127 typename EmptyField<Data_T>::Vec 01128 Field3DInputFile::readProxyLayer(const std::string &partitionName, 01129 const std::string &layerName, 01130 bool isVectorLayer) const 01131 { 01132 using namespace boost; 01133 using namespace std; 01134 using namespace Hdf5Util; 01135 01136 // Instantiate a null pointer for easier code reading 01137 typename EmptyField<Data_T>::Vec emptyList, output; 01138 01139 if ((layerName.length() == 0) || (partitionName.length() == 0)) 01140 return emptyList; 01141 01142 std::vector<std::string> parts, layers; 01143 getIntPartitionNames(parts); 01144 01145 bool foundPartition = false; 01146 01147 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01148 if (removeUniqueId(*p) == partitionName) { 01149 foundPartition = true; 01150 if (isVectorLayer) { 01151 getIntVectorLayerNames(layers, *p); 01152 } else { 01153 getIntScalarLayerNames(layers, *p); 01154 } 01155 for (vector<string>::iterator l = layers.begin(); 01156 l != layers.end(); ++l) { 01157 if (*l == layerName) { 01158 // Find the partition 01159 File::Partition::Ptr part = partition(*p); 01160 if (!part) { 01161 Msg::print(Msg::SevWarning, "Couldn't find partition: " + *p); 01162 return emptyList; 01163 } 01164 // Find the layer 01165 const File::Layer *layer; 01166 if (isVectorLayer) 01167 layer = part->vectorLayer(layerName); 01168 else 01169 layer = part->scalarLayer(layerName); 01170 if (!layer) { 01171 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName); 01172 return emptyList; 01173 } 01174 // Open the layer group 01175 string layerPath = layer->parent + "/" + layer->name; 01176 H5ScopedGopen layerGroup(m_file, layerPath.c_str()); 01177 if (layerGroup.id() < 0) { 01178 Msg::print(Msg::SevWarning, "Couldn't find layer group " 01179 + layerName + " in .f3d file "); 01180 return emptyList; 01181 } 01182 // Read the extents and data window 01183 Box3i extents, dataW; 01184 if (!readAttribute(layerGroup, "extents", 6, extents.min.x)) { 01185 return emptyList; 01186 } 01187 if (!readAttribute(layerGroup, "data_window", 6, dataW.min.x)) { 01188 return emptyList; 01189 } 01190 // Construct the field and load the data 01191 typename EmptyField<Data_T>::Ptr field(new EmptyField<Data_T>); 01192 field->setSize(extents, dataW); 01193 01194 // read the metadata 01195 string metadataPath = layerPath + "/metadata"; 01196 H5ScopedGopen metadataGroup(m_file, metadataPath.c_str()); 01197 if (metadataGroup.id() > 0) { 01198 readMetadata(metadataGroup.id(), field); 01199 } 01200 01201 // ... Set the name of the field so it's possible to 01202 // ... re-create the file 01203 field->name = partitionName; 01204 field->attribute = layerName; 01205 field->setMapping(part->mapping); 01206 // Add field to output 01207 output.push_back(field); 01208 } 01209 } 01210 } 01211 } 01212 01213 if (!foundPartition) { 01214 Msg::print(Msg::SevWarning, "Couldn't find partition: " + partitionName); 01215 return emptyList; 01216 } 01217 01218 return output; 01219 } 01220 01221 //----------------------------------------------------------------------------// 01222 01223 template <class Data_T> 01224 typename EmptyField<Data_T>::Vec 01225 Field3DInputFile::readProxyScalarLayers(const std::string &name) const 01226 { 01227 using namespace std; 01228 01229 typedef typename EmptyField<Data_T>::Ptr FieldPtr; 01230 typedef std::vector<FieldPtr> FieldList; 01231 01232 FieldList ret; 01233 01234 std::vector<std::string> parts; 01235 getPartitionNames(parts); 01236 01237 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01238 std::vector<std::string> layers; 01239 getScalarLayerNames(layers, *p); 01240 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 01241 // Only read if it matches the name 01242 if ((name.length() == 0) || (*l == name)) { 01243 FieldList f = readProxyLayer<Data_T>(*p, *l, false); 01244 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) { 01245 if (*i) { 01246 ret.push_back(*i); 01247 } 01248 } 01249 } 01250 } 01251 } 01252 01253 return ret; 01254 } 01255 01256 //----------------------------------------------------------------------------// 01257 01258 template <class Data_T> 01259 typename EmptyField<Data_T>::Vec 01260 Field3DInputFile::readProxyVectorLayers(const std::string &name) const 01261 { 01262 using namespace std; 01263 01264 typedef typename EmptyField<Data_T>::Ptr FieldPtr; 01265 typedef std::vector<FieldPtr> FieldList; 01266 01267 FieldList ret; 01268 01269 std::vector<std::string> parts; 01270 getPartitionNames(parts); 01271 01272 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01273 std::vector<std::string> layers; 01274 getVectorLayerNames(layers, *p); 01275 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 01276 // Only read if it matches the name 01277 if ((name.length() == 0) || (*l == name)) { 01278 FieldList f = readProxyLayer<Data_T>(*p, *l, true); 01279 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) { 01280 if (*i) { 01281 ret.push_back(*i); 01282 } 01283 } 01284 } 01285 } 01286 } 01287 01288 return ret; 01289 } 01290 01291 //----------------------------------------------------------------------------// 01292 01293 template <class Data_T> 01294 typename Field<Data_T>::Ptr 01295 Field3DInputFile::readScalarLayer(const std::string &intPartitionName, 01296 const std::string &layerName) const 01297 { 01298 return readLayer<Data_T>(intPartitionName, layerName, false); 01299 } 01300 01301 //----------------------------------------------------------------------------// 01302 01303 template <class Data_T> 01304 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr 01305 Field3DInputFile::readVectorLayer(const std::string &intPartitionName, 01306 const std::string &layerName) const 01307 { 01308 return readLayer<FIELD3D_VEC3_T<Data_T> >(intPartitionName, layerName, true); 01309 } 01310 01311 //----------------------------------------------------------------------------// 01312 // Field3DOutputFile 01313 //----------------------------------------------------------------------------// 01314 01315 template <class Data_T> 01316 File::Partition::Ptr 01317 Field3DOutputFile::createNewPartition(const std::string &partitionName, 01318 const std::string &layerName, 01319 typename Field<Data_T>::Ptr field) 01320 { 01321 using namespace Hdf5Util; 01322 using namespace Exc; 01323 01324 File::Partition::Ptr newPart(new File::Partition); 01325 01326 newPart->name = partitionName; 01327 01328 H5ScopedGcreate partGroup(m_file, newPart->name.c_str()); 01329 if (partGroup.id() < 0) { 01330 Msg::print(Msg::SevWarning, 01331 "Error creating partition: " + newPart->name); 01332 return File::Partition::Ptr(); 01333 } 01334 01335 m_partitions.push_back(newPart); 01336 01337 // Pick up new pointer 01338 File::Partition::Ptr part = partition(partitionName); 01339 01340 // Add mapping group to the partition 01343 try { 01344 if (!writeMapping(partGroup.id(), field->mapping())) { 01345 Msg::print(Msg::SevWarning, 01346 "writeMapping returned false for an unknown reason "); 01347 return File::Partition::Ptr(); 01348 } 01349 } 01350 catch (WriteMappingException &e) { 01351 Msg::print(Msg::SevWarning, "Couldn't write mapping for partition: " 01352 + partitionName); 01353 return File::Partition::Ptr(); 01354 } 01355 catch (...) { 01356 Msg::print(Msg::SevWarning, 01357 "Unknown error when writing mapping for partition: " 01358 + partitionName); 01359 return File::Partition::Ptr(); 01360 } 01361 01362 // Set the mapping of the partition. Since all layers share their 01363 // partition's mapping, we can just pick this first one. All subsequent 01364 // additions to the same partition are checked to have the same mapping 01365 part->mapping = field->mapping(); 01366 01367 // Tag node as partition 01368 // Create a version attribute on the root node 01369 if (!writeAttribute(partGroup.id(), "is_field3d_partition", "1")) { 01370 Msg::print(Msg::SevWarning, "Adding partition string."); 01371 return File::Partition::Ptr(); 01372 } 01373 01374 return part; 01375 } 01376 01377 //----------------------------------------------------------------------------// 01378 01379 template <class Data_T> 01380 bool 01381 Field3DOutputFile::writeLayer(const std::string &userPartitionName, 01382 const std::string &layerName, 01383 bool isVectorLayer, 01384 typename Field<Data_T>::Ptr field) 01385 { 01386 using namespace std; 01387 using namespace Exc; 01388 using namespace Hdf5Util; 01389 01390 if (!field) { 01391 Msg::print(Msg::SevWarning, 01392 "Called writeLayer with null pointer. Ignoring..."); 01393 return false; 01394 } 01395 01396 if (m_file < 0) { 01397 Msg::print(Msg::SevWarning, 01398 "Attempting to write layer without opening file first. "); 01399 return false; 01400 } 01401 01402 string partitionName = intPartitionName(userPartitionName, layerName, field); 01403 01404 // See if the partition already exists or if we need to make it --- 01405 01406 File::Partition::Ptr part = partition(partitionName); 01407 01408 if (!part) { 01409 part = createNewPartition<Data_T>(partitionName,layerName,field); 01410 if (!part) 01411 return false; 01412 } else { 01413 01414 if (!field->mapping()) { 01415 Msg::print(Msg::SevWarning, 01416 "Couldn't add layer \"" + layerName + "\" to partition \"" 01417 + partitionName + "\" because the layer's mapping is null."); 01418 return false; 01419 } 01420 01421 // If the partition already existed, we need to make sure that the layer 01422 // doesn't also exist 01423 if (!isVectorLayer) { 01424 if (part->scalarLayer(layerName)) { 01425 //need to create a new partition and then add the layer to that 01426 std::string newPartitionName = incrementPartitionName(partitionName); 01427 part = createNewPartition<Data_T>(newPartitionName,layerName,field); 01428 if (!part) 01429 return false; 01430 } 01431 } else { 01432 if (part->vectorLayer(layerName)) { 01433 //need to create a new partition and then add the layer to that 01434 std::string newPartitionName = incrementPartitionName(partitionName); 01435 part = createNewPartition<Data_T>(newPartitionName,layerName,field); 01436 if (!part) 01437 return false; 01438 } 01439 } 01440 } 01441 01442 if (!part->mapping) { 01443 Msg::print(Msg::SevWarning, "Severe error - partition mapping is null: " 01444 + partitionName); 01445 return false; 01446 } 01447 01448 // Check that the mapping matches what's already in the Partition 01449 if (!field->mapping()->isIdentical(part->mapping)) { 01450 Msg::print(Msg::SevWarning, "Couldn't add layer \"" + layerName 01451 + "\" to partition \"" + partitionName 01452 + "\" because mapping doesn't match"); 01453 return false; 01454 } 01455 01456 // Open the partition 01457 H5ScopedGopen partGroup(m_file, part->name.c_str(), H5P_DEFAULT); 01458 01459 // Build a Layer object --- 01460 01461 File::Layer layer; 01462 layer.name = layerName; 01463 layer.parent = partitionName; 01464 01465 // Add Layer to file --- 01466 01467 H5ScopedGcreate layerGroup(partGroup.id(), layerName.c_str(), 01468 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 01469 01470 if (layerGroup.id() < 0) { 01471 Msg::print(Msg::SevWarning, "Error creating layer: " + layerName); 01472 return false; 01473 } 01474 01475 // Tag as layer 01476 if (!writeAttribute(layerGroup.id(), "class_type", "field3d_layer")) { 01477 Msg::print(Msg::SevWarning, "Error adding layer string."); 01478 return false; 01479 } 01480 01481 // Add metadata group and write it out 01482 H5ScopedGcreate metadataGroup(layerGroup.id(), "metadata"); 01483 if (metadataGroup.id() < 0) { 01484 Msg::print(Msg::SevWarning, "Error creating group: metadata"); 01485 return false; 01486 } 01487 if (!writeMetadata(metadataGroup.id(), field)) { 01488 Msg::print(Msg::SevWarning, "Error writing metadata."); 01489 return false; 01490 } 01491 01492 if (!writeField(layerGroup.id(), field)) { 01493 Msg::print(Msg::SevWarning, "Error writing layer: " + layer.name); 01494 return false; 01495 } 01496 01497 // Add layer to partition --- 01498 01499 if (isVectorLayer) 01500 part->addVectorLayer(layer); 01501 else 01502 part->addScalarLayer(layer); 01503 01504 return true; 01505 } 01506 01507 //----------------------------------------------------------------------------// 01508 01509 template <class Data_T> 01510 bool 01511 Field3DOutputFile::writeScalarLayer(const std::string &partitionName, 01512 const std::string &layerName, 01513 typename Field<Data_T>::Ptr field) 01514 { 01515 return writeLayer<Data_T>(partitionName, layerName, false, field); 01516 } 01517 01518 //----------------------------------------------------------------------------// 01519 01520 template <class Data_T> 01521 bool 01522 Field3DOutputFile::writeScalarLayer(typename Field<Data_T>::Ptr layer) 01523 { 01524 if (layer->name.size() == 0) { 01525 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: " 01526 "Tried to write a scalar layer with no name"); 01527 return false; 01528 } 01529 if (layer->attribute.size() == 0) { 01530 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: " 01531 "Tried to write a scalar layer with no attribute name"); 01532 return false; 01533 } 01534 return writeScalarLayer<Data_T>(layer->name, layer->attribute, layer); 01535 } 01536 01537 //----------------------------------------------------------------------------// 01538 01539 template <class Data_T> 01540 bool 01541 Field3DOutputFile:: 01542 writeVectorLayer(const std::string &partitionName, 01543 const std::string &layerName, 01544 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr field) 01545 { 01546 return writeLayer<FIELD3D_VEC3_T<Data_T> >(partitionName, layerName, 01547 true, field); 01548 } 01549 01550 //----------------------------------------------------------------------------// 01551 01552 template <class Data_T> 01553 bool 01554 Field3DOutputFile::writeVectorLayer 01555 (typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer) 01556 { 01557 if (layer->name.size() == 0) { 01558 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: " 01559 "Tried to write a vector layer with no name"); 01560 return false; 01561 } 01562 if (layer->attribute.size() == 0) { 01563 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: " 01564 "Tried to write a vector layer with no attribute name"); 01565 return false; 01566 } 01567 return writeVectorLayer<Data_T>(layer->name, layer->attribute, layer); 01568 } 01569 01570 //----------------------------------------------------------------------------// 01571 // Template Function Implementations 01572 //----------------------------------------------------------------------------// 01573 01574 template <class Data_T> 01575 typename Field<Data_T>::Ptr 01576 readField(const std::string &className, hid_t layerGroup, 01577 const std::string &filename, const std::string &layerPath) 01578 { 01579 01580 ClassFactory &factory = ClassFactory::singleton(); 01581 01582 typedef typename Field<Data_T>::Ptr FieldPtr; 01583 01584 FieldIO::Ptr io = factory.createFieldIO(className); 01585 assert(io != 0); 01586 if (!io) { 01587 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01588 className); 01589 return FieldPtr(); 01590 } 01591 01592 DataTypeEnum typeEnum = DataTypeTraits<Data_T>::typeEnum(); 01593 FieldBase::Ptr field = io->read(layerGroup, filename, layerPath, typeEnum); 01594 01595 if (!field) { 01596 // We don't need to print a message, because it could just be that 01597 // a layer of the specified data type and name couldn't be found 01598 return FieldPtr(); 01599 } 01600 01601 FieldPtr result = field_dynamic_cast<Field<Data_T> >(field); 01602 01603 if (result) 01604 return result; 01605 01606 return FieldPtr(); 01607 } 01608 01609 //----------------------------------------------------------------------------// 01610 01611 FIELD3D_NAMESPACE_HEADER_CLOSE 01612 01613 //----------------------------------------------------------------------------// 01614 01615 #endif