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 // Ctors, dtor --------------------------------------------------------------- 00153 00155 Partition() : RefBase() {} 00156 00157 // Main methods -------------------------------------------------------------- 00158 00160 void addScalarLayer(const File::Layer &layer); 00162 void addVectorLayer(const File::Layer &layer); 00163 00165 const File::Layer* scalarLayer(const std::string &name) const; 00167 const File::Layer* vectorLayer(const std::string &name) const; 00168 00170 void getScalarLayerNames(std::vector<std::string> &names) const; 00172 void getVectorLayerNames(std::vector<std::string> &names) const; 00173 00174 // Public data members ------------------------------------------------------- 00175 00177 std::string name; 00179 FieldMapping::Ptr mapping; 00180 00181 private: 00182 00183 // Private data members ------------------------------------------------------ 00184 00186 ScalarLayerList m_scalarLayers; 00188 VectorLayerList m_vectorLayers; 00189 00190 }; 00191 00192 00193 } // namespace File 00194 00195 //----------------------------------------------------------------------------// 00196 // Field3DFileBase 00197 //----------------------------------------------------------------------------// 00198 00206 //----------------------------------------------------------------------------// 00207 00208 class Field3DFileBase 00209 { 00210 public: 00211 00212 // Structs ------------------------------------------------------------------- 00213 00214 struct LayerInfo 00215 { 00216 std::string name; 00217 std::string parentName; 00218 int components; 00219 LayerInfo(std::string par, std::string nm, int cpt) 00220 : name(nm), parentName(par), components(cpt) 00221 { /* Empty */ } 00222 }; 00223 00224 // Typedefs ------------------------------------------------------------------ 00225 00226 typedef std::map<std::string, std::string> GroupMembershipMap; 00227 00228 // Ctor, dtor ---------------------------------------------------------------- 00229 00232 00233 Field3DFileBase(); 00235 virtual ~Field3DFileBase() = 0; 00236 00238 00239 // Main methods -------------------------------------------------------------- 00240 00242 void clear(); 00243 00247 bool close(); 00248 00251 00253 void getPartitionNames(std::vector<std::string> &names) const; 00255 void getScalarLayerNames(std::vector<std::string> &names, 00256 const std::string &partitionName) const; 00258 void getVectorLayerNames(std::vector<std::string> &names, 00259 const std::string &partitionName) const; 00260 00263 File::Partition::Ptr getPartition(const std::string &partitionName) const 00264 { return partition(partitionName); } 00265 00267 00270 00274 std::string intPartitionName(const std::string &partitionName, 00275 const std::string &layerName, 00276 FieldRes::Ptr field); 00277 00280 std::string removeUniqueId(const std::string &partitionName) const; 00281 00283 void addGroupMembership(const GroupMembershipMap &groupMembers); 00284 00286 00287 // Access to metadata -------------------------------------------------------- 00288 00290 FieldMetadata<Field3DFileBase>& metadata() 00291 { return m_metadata; } 00292 00294 const FieldMetadata<Field3DFileBase>& metadata() const 00295 { return m_metadata; } 00296 00299 virtual void metadataHasChanged(const std::string &/* name */) 00300 { /* Empty */ } 00301 00302 // Debug --------------------------------------------------------------------- 00303 00306 00307 void printHierarchy() const; 00308 00310 00311 protected: 00312 00313 // Internal typedefs --------------------------------------------------------- 00314 00315 typedef std::vector<File::Partition::Ptr> PartitionList; 00316 typedef std::map<std::string, int> PartitionCountMap; 00317 00318 // Convenience methods ------------------------------------------------------- 00319 00322 00324 void closeInternal(); 00327 File::Partition::Ptr partition(const std::string &partitionName); 00330 File::Partition::Ptr partition(const std::string &partitionName) const; 00331 00333 void getIntPartitionNames(std::vector<std::string> &names) const; 00336 void getIntScalarLayerNames(std::vector<std::string> &names, 00337 const std::string &intPartitionName) const; 00340 void getIntVectorLayerNames(std::vector<std::string> &names, 00341 const std::string &intPartitionName) const; 00342 00344 int numIntPartitions(const std::string &partitionName) const; 00345 00348 std::string makeIntPartitionName(const std::string &partitionsName, 00349 int i) const; 00350 00352 00353 // Data members -------------------------------------------------------------- 00354 00356 std::vector<LayerInfo> m_layerInfo; 00357 00359 hid_t m_file; 00361 PartitionList m_partitions; 00363 std::vector<std::string> m_partitionNames; 00364 00367 PartitionCountMap m_partitionCount; 00368 00372 GroupMembershipMap m_groupMembership; 00373 00375 FieldMetadata<Field3DFileBase> m_metadata; 00376 00377 private: 00378 00379 // Private member functions -------------------------------------------------- 00380 00381 Field3DFileBase(const Field3DFileBase&); 00382 void operator =(const Field3DFileBase&); 00383 00384 00385 }; 00386 00387 //----------------------------------------------------------------------------// 00388 // Field3DInputFile 00389 //----------------------------------------------------------------------------// 00390 00404 //----------------------------------------------------------------------------// 00405 00406 class Field3DInputFile : public Field3DFileBase 00407 { 00408 public: 00409 00410 // Ctors, dtor --------------------------------------------------------------- 00411 00414 00415 Field3DInputFile(); 00416 virtual ~Field3DInputFile(); 00417 00419 00420 // Main interface ------------------------------------------------------------ 00421 00424 00429 template <class Data_T> 00430 typename Field<Data_T>::Vec 00431 readScalarLayers(const std::string &layerName = std::string("")) const; 00432 00434 template <class Data_T> 00435 typename Field<Data_T>::Vec 00436 readScalarLayers(const std::string &partitionName, 00437 const std::string &layerName) const; 00438 00443 template <class Data_T> 00444 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00445 readVectorLayers(const std::string &layerName = std::string("")) const; 00446 00448 template <class Data_T> 00449 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00450 readVectorLayers(const std::string &partitionName, 00451 const std::string &layerName) const; 00452 00455 template <template <typename T> class Field_T, class Data_T> 00456 typename Field_T<Data_T>::Vec 00457 readScalarLayersAs(const std::string &layerName = std::string("")) const; 00458 00461 template <template <typename T> class Field_T, class Data_T> 00462 typename Field_T<Data_T>::Vec 00463 readScalarLayersAs(const std::string &partitionName, 00464 const std::string &layerName) const; 00465 00468 template <template <typename T> class Field_T, class Data_T> 00469 typename Field_T<Data_T>::Vec 00470 readVectorLayersAs(const std::string &layerName = std::string("")) const; 00471 00474 template <template <typename T> class Field_T, class Data_T> 00475 typename Field_T<Data_T>::Vec 00476 readVectorLayersAs(const std::string &partitionName, 00477 const std::string &layerName) const; 00478 00480 00483 00487 template <class Data_T> 00488 typename EmptyField<Data_T>::Vec 00489 readProxyLayer(const std::string &partitionName, 00490 const std::string &layerName, 00491 bool isVectorLayer) const; 00492 00496 template <class Data_T> 00497 typename EmptyField<Data_T>::Vec 00498 readProxyScalarLayers(const std::string &name = std::string("")) const; 00499 00503 template <class Data_T> 00504 typename EmptyField<Data_T>::Vec 00505 readProxyVectorLayers(const std::string &name = std::string("")) const; 00506 00508 00509 // File IO --- 00510 00513 bool open(const std::string &filename); 00514 00515 // Callback convenience methods ---------------------------------------------- 00516 00519 00521 herr_t parsePartition(hid_t loc_id, const std::string partitionName); 00522 00524 herr_t parseLayer(hid_t loc_id, const std::string &partitionName, 00525 const std::string &layerName); 00526 00528 00529 // Convenience methods ------------------------------------------------------- 00530 00532 bool readGroupMembership(GroupMembershipMap &gpMembershipMap); 00533 00534 00535 private: 00536 00537 // Convenience methods ------------------------------------------------------- 00538 00541 template <class Data_T> 00542 typename Field<Data_T>::Ptr 00543 readScalarLayer(const std::string &intPartitionName, 00544 const std::string &layerName) const; 00545 00548 template <class Data_T> 00549 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr 00550 readVectorLayer(const std::string &intPartitionName, 00551 const std::string &layerName) const; 00552 00555 template <class Data_T> 00556 typename Field<Data_T>::Ptr 00557 readLayer(const std::string &intPartitionName, 00558 const std::string &layerName, 00559 bool isVectorLayer) const; 00560 00562 bool readPartitionAndLayerInfo(); 00563 00565 bool readMetadata(hid_t metadata_id, FieldBase::Ptr field) const; 00566 00568 bool readMetadata(hid_t metadata_id); 00569 00570 // Data members -------------------------------------------------------------- 00571 00573 std::string m_filename; 00574 00575 }; 00576 00577 //----------------------------------------------------------------------------// 00578 // Field3DOutputFile 00579 //----------------------------------------------------------------------------// 00580 00594 //----------------------------------------------------------------------------// 00595 00596 class Field3DOutputFile : public Field3DFileBase 00597 { 00598 public: 00599 00600 // Enums --------------------------------------------------------------------- 00601 00602 enum CreateMode { 00603 OverwriteMode, 00604 FailOnExisting 00605 }; 00606 00607 // Ctors, dtor --------------------------------------------------------------- 00608 00611 00612 Field3DOutputFile(); 00613 virtual ~Field3DOutputFile(); 00614 00616 00617 // Main interface ------------------------------------------------------------ 00618 00621 00623 template <class Data_T> 00624 bool writeScalarLayer(const std::string &layerName, 00625 typename Field<Data_T>::Ptr layer) 00626 { return writeScalarLayer<Data_T>(layerName, std::string("default"), layer); } 00627 00629 template <class Data_T> 00630 bool writeVectorLayer(const std::string &layerName, 00631 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer) 00632 { return writeVectorLayer<Data_T>(layerName, std::string("default"), layer); } 00633 00636 template <class Data_T> 00637 bool writeScalarLayer(const std::string &partitionName, 00638 const std::string &layerName, 00639 typename Field<Data_T>::Ptr layer); 00640 00643 template <class Data_T> 00644 bool writeScalarLayer(typename Field<Data_T>::Ptr layer); 00645 00648 template <class Data_T> 00649 bool writeVectorLayer(const std::string &partitionName, 00650 const std::string &layerName, 00651 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer); 00652 00655 template <class Data_T> 00656 bool writeVectorLayer(typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer); 00657 00659 00661 bool create(const std::string &filename, CreateMode cm = OverwriteMode); 00662 00664 bool writeGlobalMetadata(); 00665 00668 bool writeGroupMembership(); 00669 00670 private: 00671 00672 // Convenience methods ------------------------------------------------------- 00673 00677 bool writeMapping(hid_t partitionLocation, FieldMapping::Ptr mapping); 00678 00680 template <class Data_T> 00681 bool writeLayer(const std::string &partitionName, 00682 const std::string &layerName, 00683 bool isVectorLayer, 00684 typename Field<Data_T>::Ptr layer); 00685 00687 bool writeMetadata(hid_t metadataGroup, FieldBase::Ptr layer); 00688 00690 bool writeMetadata(hid_t metadataGroup); 00691 00692 }; 00693 00694 //----------------------------------------------------------------------------// 00695 // Field3DInputFile-related callback functions 00696 //----------------------------------------------------------------------------// 00697 00699 namespace InputFile { 00700 00704 struct ParseLayersInfo 00705 { 00706 Field3DInputFile *file; 00707 std::string partitionName; 00708 }; 00709 00713 herr_t parsePartitions(hid_t loc_id, const char *partitionName, 00714 const H5L_info_t *linfo, void *opdata); 00715 00719 herr_t parseLayers(hid_t loc_id, const char *partitionName, 00720 const H5L_info_t *linfo, void *opdata); 00721 00722 } // namespace InputFile 00723 00724 //----------------------------------------------------------------------------// 00725 // Field3DInputFile 00726 //----------------------------------------------------------------------------// 00727 00728 template <class Data_T> 00729 typename Field<Data_T>::Vec 00730 Field3DInputFile::readScalarLayers(const std::string &name) const 00731 { 00732 using namespace std; 00733 00734 typedef typename Field<Data_T>::Ptr FieldPtr; 00735 typedef typename Field<Data_T>::Vec FieldList; 00736 00737 FieldList ret; 00738 std::vector<std::string> parts; 00739 getIntPartitionNames(parts); 00740 00741 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00742 std::vector<std::string> layers; 00743 getIntScalarLayerNames(layers, *p); 00744 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 00745 // Only read if it matches the name 00746 if ((name.length() == 0) || (*l == name)) { 00747 FieldPtr mf = readScalarLayer<Data_T>(*p, *l); 00748 if (mf) { 00749 ret.push_back(mf); 00750 } 00751 } 00752 } 00753 } 00754 00755 return ret; 00756 } 00757 00758 //----------------------------------------------------------------------------// 00759 00760 template <class Data_T> 00761 typename Field<Data_T>::Vec 00762 Field3DInputFile::readScalarLayers(const std::string &partitionName, 00763 const std::string &layerName) const 00764 { 00765 using namespace std; 00766 00767 typedef typename Field<Data_T>::Ptr FieldPtr; 00768 typedef typename Field<Data_T>::Vec FieldList; 00769 00770 FieldList ret; 00771 00772 if ((layerName.length() == 0) || (partitionName.length() == 0)) 00773 return ret; 00774 00775 std::vector<std::string> parts; 00776 getIntPartitionNames(parts); 00777 00778 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00779 std::vector<std::string> layers; 00780 getIntScalarLayerNames(layers, *p); 00781 if (removeUniqueId(*p) == partitionName) { 00782 for (vector<string>::iterator l = layers.begin(); 00783 l != layers.end(); ++l) { 00784 // Only read if it matches the name 00785 if (*l == layerName) { 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<FIELD3D_VEC3_T<Data_T> >::Vec 00801 Field3DInputFile::readVectorLayers(const std::string &name) const 00802 { 00803 using namespace std; 00804 00805 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr; 00806 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList; 00807 00808 FieldList ret; 00809 00810 std::vector<std::string> parts; 00811 getIntPartitionNames(parts); 00812 00813 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00814 std::vector<std::string> layers; 00815 getIntVectorLayerNames(layers, *p); 00816 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 00817 // Only read if it matches the name 00818 if ((name.length() == 0) || (*l == name)) { 00819 FieldPtr mf = readVectorLayer<Data_T>(*p, *l); 00820 if (mf) 00821 ret.push_back(mf); 00822 } 00823 } 00824 } 00825 00826 return ret; 00827 } 00828 00829 //----------------------------------------------------------------------------// 00830 00831 template <class Data_T> 00832 typename Field<FIELD3D_VEC3_T<Data_T> >::Vec 00833 Field3DInputFile::readVectorLayers(const std::string &partitionName, 00834 const std::string &layerName) const 00835 { 00836 using namespace std; 00837 00838 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr FieldPtr; 00839 typedef typename Field<FIELD3D_VEC3_T<Data_T> >::Vec FieldList; 00840 00841 FieldList ret; 00842 00843 if ((layerName.length() == 0) || (partitionName.length() == 0)) 00844 return ret; 00845 00846 std::vector<std::string> parts; 00847 getIntPartitionNames(parts); 00848 00849 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 00850 std::vector<std::string> layers; 00851 getIntVectorLayerNames(layers, *p); 00852 if (removeUniqueId(*p) == partitionName) { 00853 for (vector<string>::iterator l = layers.begin(); 00854 l != layers.end(); ++l) { 00855 // Only read if it matches the name 00856 if (*l == layerName) { 00857 FieldPtr mf = readVectorLayer<Data_T>(*p, *l); 00858 if (mf) 00859 ret.push_back(mf); 00860 } 00861 } 00862 } 00863 } 00864 00865 return ret; 00866 } 00867 00868 //----------------------------------------------------------------------------// 00869 00870 template <class Data_T> 00871 typename Field<Data_T>::Ptr 00872 Field3DInputFile::readLayer(const std::string &intPartitionName, 00873 const std::string &layerName, 00874 bool isVectorLayer) const 00875 { 00876 using namespace boost; 00877 using namespace std; 00878 using namespace Hdf5Util; 00879 00880 // Instantiate a null pointer for easier code reading 00881 typename Field<Data_T>::Ptr nullPtr; 00882 00883 // Find the partition 00884 File::Partition::Ptr part = partition(intPartitionName); 00885 if (!part) { 00886 Msg::print(Msg::SevWarning, "Couldn't find partition: " + intPartitionName); 00887 return nullPtr; 00888 } 00889 00890 // Find the layer in the partition 00891 const File::Layer *l; 00892 if (isVectorLayer) 00893 l = part->vectorLayer(layerName); 00894 else 00895 l = part->scalarLayer(layerName); 00896 if (!l) { 00897 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName ); 00898 return nullPtr; 00899 } 00900 00901 // Open the layer group 00902 string layerPath = l->parent + "/" + l->name; 00903 H5ScopedGopen layerGroup(m_file, layerPath.c_str()); 00904 00905 if (layerGroup.id() < 0) { 00906 Msg::print(Msg::SevWarning, "Couldn't find layer group " + layerName 00907 + " in .f3d file "); 00908 return nullPtr; 00909 } 00910 00911 // Get the class name 00912 string className; 00913 if (!readAttribute(layerGroup.id(), "class_name", className)) { 00914 Msg::print(Msg::SevWarning, "Couldn't find class_name attrib in layer " + 00915 layerName); 00916 return nullPtr; 00917 } 00918 00919 00920 // Construct the field and load the data 00921 00922 typename Field<Data_T>::Ptr field; 00923 field = readField<Data_T>(className, layerGroup.id(), m_filename, layerPath); 00924 00925 if (!field) { 00926 #if 0 // This isn't really an error 00927 Msg::print(Msg::SevWarning, "Couldn't read the layer data of layer: " 00928 + layerName); 00929 #endif 00930 return nullPtr; 00931 } 00932 00933 // read the metadata 00934 string metadataPath = layerPath + "/metadata"; 00935 H5ScopedGopen metadataGroup(m_file, metadataPath.c_str()); 00936 if (metadataGroup.id() > 0) { 00937 readMetadata(metadataGroup.id(), field); 00938 } 00939 00940 // Set the name of the field so it's possible to re-create the file 00941 field->name = removeUniqueId(intPartitionName); 00942 field->attribute = layerName; 00943 field->setMapping(part->mapping); 00944 00945 return field; 00946 } 00947 00948 //----------------------------------------------------------------------------// 00949 00950 template <template <typename T> class Field_T, class Data_T> 00951 typename Field_T<Data_T>::Vec 00952 Field3DInputFile::readScalarLayersAs(const std::string &layerName) const 00953 { 00954 typedef typename Field<Data_T>::Vec FieldList; 00955 typedef typename Field_T<Data_T>::Vec TypedFieldList; 00956 00957 // First, read the layers as-is 00958 FieldList originals; 00959 originals = readScalarLayers<Data_T>(layerName); 00960 00961 // Loop over fields, converting if needed 00962 TypedFieldList output; 00963 typename FieldList::iterator i = originals.begin(); 00964 for (; i != originals.end(); ++i) { 00965 typename Field_T<Data_T>::Ptr targetField; 00966 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 00967 if (targetField) { 00968 output.push_back(targetField); 00969 } else { 00970 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 00971 newTarget->name = (*i)->name; 00972 newTarget->attribute = (*i)->attribute; 00973 newTarget->copyMetadata(*i); 00974 newTarget->copyFrom(*i); 00975 output.push_back(newTarget); 00976 } 00977 } 00978 00979 return output; 00980 } 00981 00982 //----------------------------------------------------------------------------// 00983 00984 template <template <typename T> class Field_T, class Data_T> 00985 typename Field_T<Data_T>::Vec 00986 Field3DInputFile::readScalarLayersAs(const std::string &partitionName, 00987 const std::string &layerName) const 00988 { 00989 typedef typename Field<Data_T>::Vec FieldList; 00990 typedef typename Field_T<Data_T>::Vec TypedFieldList; 00991 00992 // First, read the layers as-is 00993 FieldList originals; 00994 originals = readScalarLayers<Data_T>(partitionName, layerName); 00995 00996 // Loop over fields, converting if needed 00997 TypedFieldList output; 00998 typename FieldList::iterator i = originals.begin(); 00999 for (; i != originals.end(); ++i) { 01000 typename Field_T<Data_T>::Ptr targetField; 01001 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01002 if (targetField) { 01003 output.push_back(targetField); 01004 } else { 01005 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01006 newTarget->name = (*i)->name; 01007 newTarget->attribute = (*i)->attribute; 01008 newTarget->copyMetadata(**i); 01009 newTarget->copyFrom(*i); 01010 output.push_back(newTarget); 01011 } 01012 } 01013 01014 return output; 01015 } 01016 01017 //----------------------------------------------------------------------------// 01018 01019 template <template <typename T> class Field_T, class Data_T> 01020 typename Field_T<Data_T>::Vec 01021 Field3DInputFile::readVectorLayersAs(const std::string &layerName) const 01022 { 01023 typedef typename Field<Data_T>::Vec FieldList; 01024 typedef typename Field_T<Data_T>::Vec TypedFieldList; 01025 01026 // First, read the layers as-is 01027 FieldList originals; 01028 originals = readVectorLayers<Data_T>(layerName); 01029 01030 // Loop over fields, converting if needed 01031 TypedFieldList output; 01032 typename FieldList::iterator i = originals.begin(); 01033 for (; i != originals.end(); ++i) { 01034 typename Field_T<Data_T>::Ptr targetField; 01035 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01036 if (targetField) { 01037 output.push_back(targetField); 01038 } else { 01039 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01040 newTarget->name = (*i)->name; 01041 newTarget->attribute = (*i)->attribute; 01042 newTarget->copyMetadata(*i); 01043 newTarget->copyFrom(*i); 01044 output.push_back(newTarget); 01045 } 01046 } 01047 01048 return output; 01049 } 01050 01051 //----------------------------------------------------------------------------// 01052 01053 template <template <typename T> class Field_T, class Data_T> 01054 typename Field_T<Data_T>::Vec 01055 Field3DInputFile::readVectorLayersAs(const std::string &partitionName, 01056 const std::string &layerName) const 01057 { 01058 typedef typename Field<Data_T>::Vec FieldList; 01059 typedef typename Field_T<Data_T>::Vec TypedFieldList; 01060 01061 // First, read the layers as-is 01062 FieldList originals; 01063 originals = readVectorLayers<Data_T>(partitionName, layerName); 01064 01065 // Loop over fields, converting if needed 01066 TypedFieldList output; 01067 typename FieldList::iterator i = originals.begin(); 01068 for (; i != originals.end(); ++i) { 01069 typename Field_T<Data_T>::Ptr targetField; 01070 targetField = field_dynamic_cast<Field_T<Data_T> >(*i); 01071 if (targetField) { 01072 output.push_back(targetField); 01073 } else { 01074 typename Field_T<Data_T>::Ptr newTarget(new Field_T<Data_T>); 01075 newTarget->name = (*i)->name; 01076 newTarget->attribute = (*i)->attribute; 01077 newTarget->copyMetadata(*i); 01078 newTarget->copyFrom(*i); 01079 output.push_back(newTarget); 01080 } 01081 } 01082 01083 return output; 01084 } 01085 01086 //----------------------------------------------------------------------------// 01087 01088 template <class Data_T> 01089 typename EmptyField<Data_T>::Vec 01090 Field3DInputFile::readProxyLayer(const std::string &partitionName, 01091 const std::string &layerName, 01092 bool isVectorLayer) const 01093 { 01094 using namespace boost; 01095 using namespace std; 01096 using namespace Hdf5Util; 01097 01098 // Instantiate a null pointer for easier code reading 01099 typename EmptyField<Data_T>::Vec emptyList, output; 01100 01101 if ((layerName.length() == 0) || (partitionName.length() == 0)) 01102 return emptyList; 01103 01104 std::vector<std::string> parts, layers; 01105 getIntPartitionNames(parts); 01106 01107 bool foundPartition = false; 01108 01109 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01110 if (removeUniqueId(*p) == partitionName) { 01111 foundPartition = true; 01112 if (isVectorLayer) { 01113 getIntVectorLayerNames(layers, *p); 01114 } else { 01115 getIntScalarLayerNames(layers, *p); 01116 } 01117 for (vector<string>::iterator l = layers.begin(); 01118 l != layers.end(); ++l) { 01119 if (*l == layerName) { 01120 // Find the partition 01121 File::Partition::Ptr part = partition(*p); 01122 if (!part) { 01123 Msg::print(Msg::SevWarning, "Couldn't find partition: " + *p); 01124 return emptyList; 01125 } 01126 // Find the layer 01127 const File::Layer *layer; 01128 if (isVectorLayer) 01129 layer = part->vectorLayer(layerName); 01130 else 01131 layer = part->scalarLayer(layerName); 01132 if (!layer) { 01133 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName); 01134 return emptyList; 01135 } 01136 // Open the layer group 01137 string layerPath = layer->parent + "/" + layer->name; 01138 H5ScopedGopen layerGroup(m_file, layerPath.c_str()); 01139 if (layerGroup.id() < 0) { 01140 Msg::print(Msg::SevWarning, "Couldn't find layer group " 01141 + layerName + " in .f3d file "); 01142 return emptyList; 01143 } 01144 // Read the extents and data window 01145 Box3i extents, dataW; 01146 if (!readAttribute(layerGroup, "extents", 6, extents.min.x)) { 01147 return emptyList; 01148 } 01149 if (!readAttribute(layerGroup, "data_window", 6, dataW.min.x)) { 01150 return emptyList; 01151 } 01152 // Construct the field and load the data 01153 typename EmptyField<Data_T>::Ptr field(new EmptyField<Data_T>); 01154 field->setSize(extents, dataW); 01155 01156 // read the metadata 01157 string metadataPath = layerPath + "/metadata"; 01158 H5ScopedGopen metadataGroup(m_file, metadataPath.c_str()); 01159 if (metadataGroup.id() > 0) { 01160 readMetadata(metadataGroup.id(), field); 01161 } 01162 01163 // ... Set the name of the field so it's possible to 01164 // ... re-create the file 01165 field->name = partitionName; 01166 field->attribute = layerName; 01167 field->setMapping(part->mapping); 01168 // Add field to output 01169 output.push_back(field); 01170 } 01171 } 01172 } 01173 } 01174 01175 if (!foundPartition) { 01176 Msg::print(Msg::SevWarning, "Couldn't find partition: " + partitionName); 01177 return emptyList; 01178 } 01179 01180 return output; 01181 } 01182 01183 //----------------------------------------------------------------------------// 01184 01185 template <class Data_T> 01186 typename EmptyField<Data_T>::Vec 01187 Field3DInputFile::readProxyScalarLayers(const std::string &name) const 01188 { 01189 using namespace std; 01190 01191 typedef typename EmptyField<Data_T>::Ptr FieldPtr; 01192 typedef std::vector<FieldPtr> FieldList; 01193 01194 FieldList ret; 01195 01196 std::vector<std::string> parts; 01197 getPartitionNames(parts); 01198 01199 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01200 std::vector<std::string> layers; 01201 getScalarLayerNames(layers, *p); 01202 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 01203 // Only read if it matches the name 01204 if ((name.length() == 0) || (*l == name)) { 01205 FieldList f = readProxyLayer<Data_T>(*p, *l, false); 01206 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) { 01207 if (*i) { 01208 ret.push_back(*i); 01209 } 01210 } 01211 } 01212 } 01213 } 01214 01215 return ret; 01216 } 01217 01218 //----------------------------------------------------------------------------// 01219 01220 template <class Data_T> 01221 typename EmptyField<Data_T>::Vec 01222 Field3DInputFile::readProxyVectorLayers(const std::string &name) const 01223 { 01224 using namespace std; 01225 01226 typedef typename EmptyField<Data_T>::Ptr FieldPtr; 01227 typedef std::vector<FieldPtr> FieldList; 01228 01229 FieldList ret; 01230 01231 std::vector<std::string> parts; 01232 getPartitionNames(parts); 01233 01234 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) { 01235 std::vector<std::string> layers; 01236 getVectorLayerNames(layers, *p); 01237 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) { 01238 // Only read if it matches the name 01239 if ((name.length() == 0) || (*l == name)) { 01240 FieldList f = readProxyLayer<Data_T>(*p, *l, true); 01241 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) { 01242 if (*i) { 01243 ret.push_back(*i); 01244 } 01245 } 01246 } 01247 } 01248 } 01249 01250 return ret; 01251 } 01252 01253 //----------------------------------------------------------------------------// 01254 01255 template <class Data_T> 01256 typename Field<Data_T>::Ptr 01257 Field3DInputFile::readScalarLayer(const std::string &intPartitionName, 01258 const std::string &layerName) const 01259 { 01260 return readLayer<Data_T>(intPartitionName, layerName, false); 01261 } 01262 01263 //----------------------------------------------------------------------------// 01264 01265 template <class Data_T> 01266 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr 01267 Field3DInputFile::readVectorLayer(const std::string &intPartitionName, 01268 const std::string &layerName) const 01269 { 01270 return readLayer<FIELD3D_VEC3_T<Data_T> >(intPartitionName, layerName, true); 01271 } 01272 01273 //----------------------------------------------------------------------------// 01274 // Field3DOutputFile 01275 //----------------------------------------------------------------------------// 01276 01277 template <class Data_T> 01278 bool 01279 Field3DOutputFile::writeLayer(const std::string &userPartitionName, 01280 const std::string &layerName, 01281 bool isVectorLayer, 01282 typename Field<Data_T>::Ptr field) 01283 { 01284 using namespace std; 01285 using namespace Exc; 01286 using namespace Hdf5Util; 01287 01288 if (!field) { 01289 Msg::print(Msg::SevWarning, 01290 "Called writeLayer with null pointer. Ignoring..."); 01291 return false; 01292 } 01293 01294 if (m_file < 0) { 01295 Msg::print(Msg::SevWarning, 01296 "Attempting to write layer without opening file first. "); 01297 return false; 01298 } 01299 01300 string partitionName = intPartitionName(userPartitionName, layerName, field); 01301 01302 // See if the partition already exists or if we need to make it --- 01303 01304 File::Partition::Ptr part = partition(partitionName); 01305 01306 if (!part) { 01307 01308 File::Partition::Ptr newPart(new File::Partition); 01309 01310 newPart->name = partitionName; 01311 01312 H5ScopedGcreate partGroup(m_file, newPart->name.c_str()); 01313 if (partGroup.id() < 0) { 01314 Msg::print(Msg::SevWarning, 01315 "Error creating partition: " + newPart->name); 01316 return false; 01317 } 01318 01319 m_partitions.push_back(newPart); 01320 01321 // Pick up new pointer 01322 part = partition(partitionName); 01323 01324 // Add mapping group to the partition 01327 try { 01328 if (!writeMapping(partGroup.id(), field->mapping())) { 01329 Msg::print(Msg::SevWarning, 01330 "writeMapping returned false for an unknown reason "); 01331 return false; 01332 } 01333 } 01334 catch (WriteMappingException &e) { 01335 Msg::print(Msg::SevWarning, "Couldn't write mapping for partition: " 01336 + partitionName); 01337 return false; 01338 } 01339 catch (...) { 01340 Msg::print(Msg::SevWarning, 01341 "Unknown error when writing mapping for partition: " 01342 + partitionName); 01343 return false; 01344 } 01345 01346 // Set the mapping of the partition. Since all layers share their 01347 // partition's mapping, we can just pick this first one. All subsequent 01348 // additions to the same partition are checked to have the same mapping 01349 part->mapping = field->mapping(); 01350 01351 // Tag node as partition 01352 // Create a version attribute on the root node 01353 if (!writeAttribute(partGroup.id(), "is_field3d_partition", "1")) { 01354 Msg::print(Msg::SevWarning, "Adding partition string."); 01355 return false; 01356 } 01357 01358 } else { 01359 01360 // If the partition already existed, we need to make sure that the layer 01361 // doesn't also exist 01362 if (!isVectorLayer) { 01363 if (part->scalarLayer(layerName)) { 01364 Msg::print(Msg::SevWarning, 01365 "Trying to add layer that already exists in file. Ignoring"); 01366 return false; 01367 } 01368 } else { 01369 if (part->vectorLayer(layerName)) { 01370 Msg::print(Msg::SevWarning, 01371 "Trying to add layer that already exists in file. Ignoring"); 01372 return false; 01373 } 01374 } 01375 } 01376 01377 if (!field->mapping()) { 01378 Msg::print(Msg::SevWarning, 01379 "Couldn't add layer \"" + layerName + "\" to partition \"" 01380 + partitionName + "\" because the layer's mapping is null."); 01381 return false; 01382 } 01383 01384 if (!part->mapping) { 01385 Msg::print(Msg::SevWarning, "Severe error - partition mapping is null: " 01386 + partitionName); 01387 return false; 01388 } 01389 01390 // Check that the mapping matches what's already in the Partition 01391 if (!field->mapping()->isIdentical(part->mapping)) { 01392 Msg::print(Msg::SevWarning, "Couldn't add layer \"" + layerName 01393 + "\" to partition \"" + partitionName 01394 + "\" because mapping doesn't match"); 01395 return false; 01396 } 01397 01398 // Open the partition 01399 H5ScopedGopen partGroup(m_file, part->name.c_str(), H5P_DEFAULT); 01400 01401 // Build a Layer object --- 01402 01403 File::Layer layer; 01404 layer.name = layerName; 01405 layer.parent = partitionName; 01406 01407 // Add Layer to file --- 01408 01409 H5ScopedGcreate layerGroup(partGroup.id(), layerName.c_str(), 01410 H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT); 01411 01412 if (layerGroup.id() < 0) { 01413 Msg::print(Msg::SevWarning, "Error creating layer: " + layerName); 01414 return false; 01415 } 01416 01417 // Tag as layer 01418 if (!writeAttribute(layerGroup.id(), "class_type", "field3d_layer")) { 01419 Msg::print(Msg::SevWarning, "Error adding layer string."); 01420 return false; 01421 } 01422 01423 // Add metadata group and write it out 01424 H5ScopedGcreate metadataGroup(layerGroup.id(), "metadata"); 01425 if (metadataGroup.id() < 0) { 01426 Msg::print(Msg::SevWarning, "Error creating group: metadata"); 01427 return false; 01428 } 01429 if (!writeMetadata(metadataGroup.id(), field)) { 01430 Msg::print(Msg::SevWarning, "Error writing metadata."); 01431 return false; 01432 } 01433 01434 if (!writeField(layerGroup.id(), field)) { 01435 Msg::print(Msg::SevWarning, "Error writing layer: " + layer.name); 01436 return false; 01437 } 01438 01439 // Add layer to partition --- 01440 01441 if (isVectorLayer) 01442 part->addVectorLayer(layer); 01443 else 01444 part->addScalarLayer(layer); 01445 01446 return true; 01447 } 01448 01449 //----------------------------------------------------------------------------// 01450 01451 template <class Data_T> 01452 bool 01453 Field3DOutputFile::writeScalarLayer(const std::string &partitionName, 01454 const std::string &layerName, 01455 typename Field<Data_T>::Ptr field) 01456 { 01457 return writeLayer<Data_T>(partitionName, layerName, false, field); 01458 } 01459 01460 //----------------------------------------------------------------------------// 01461 01462 template <class Data_T> 01463 bool 01464 Field3DOutputFile::writeScalarLayer(typename Field<Data_T>::Ptr layer) 01465 { 01466 if (layer->name.size() == 0) { 01467 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: " 01468 "Tried to write a scalar layer with no name"); 01469 return false; 01470 } 01471 if (layer->attribute.size() == 0) { 01472 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeScalarLayer: " 01473 "Tried to write a scalar layer with no attribute name"); 01474 return false; 01475 } 01476 return writeScalarLayer<Data_T>(layer->name, layer->attribute, layer); 01477 } 01478 01479 //----------------------------------------------------------------------------// 01480 01481 template <class Data_T> 01482 bool 01483 Field3DOutputFile:: 01484 writeVectorLayer(const std::string &partitionName, 01485 const std::string &layerName, 01486 typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr field) 01487 { 01488 return writeLayer<FIELD3D_VEC3_T<Data_T> >(partitionName, layerName, 01489 true, field); 01490 } 01491 01492 //----------------------------------------------------------------------------// 01493 01494 template <class Data_T> 01495 bool 01496 Field3DOutputFile::writeVectorLayer 01497 (typename Field<FIELD3D_VEC3_T<Data_T> >::Ptr layer) 01498 { 01499 if (layer->name.size() == 0) { 01500 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: " 01501 "Tried to write a vector layer with no name"); 01502 return false; 01503 } 01504 if (layer->attribute.size() == 0) { 01505 Msg::print(Msg::SevWarning, "Field3DOutputFile::writeVectorLayer: " 01506 "Tried to write a vector layer with no attribute name"); 01507 return false; 01508 } 01509 return writeVectorLayer<Data_T>(layer->name, layer->attribute, layer); 01510 } 01511 01512 //----------------------------------------------------------------------------// 01513 // Template Function Implementations 01514 //----------------------------------------------------------------------------// 01515 01516 template <class Data_T> 01517 typename Field<Data_T>::Ptr 01518 readField(const std::string &className, hid_t layerGroup, 01519 const std::string &filename, const std::string &layerPath) 01520 { 01521 01522 ClassFactory &factory = ClassFactory::singleton(); 01523 01524 typedef typename Field<Data_T>::Ptr FieldPtr; 01525 01526 FieldIO::Ptr io = factory.createFieldIO(className); 01527 assert(io != 0); 01528 if (!io) { 01529 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01530 className); 01531 return FieldPtr(); 01532 } 01533 01534 DataTypeEnum typeEnum = DataTypeTraits<Data_T>::typeEnum(); 01535 FieldBase::Ptr field = io->read(layerGroup, filename, layerPath, typeEnum); 01536 01537 if (!field) { 01538 // We don't need to print a message, because it could just be that 01539 // a layer of the specified data type and name couldn't be found 01540 return FieldPtr(); 01541 } 01542 01543 FieldPtr result = field_dynamic_cast<Field<Data_T> >(field); 01544 01545 if (result) 01546 return result; 01547 01548 return FieldPtr(); 01549 } 01550 01551 //----------------------------------------------------------------------------// 01552 01553 FIELD3D_NAMESPACE_HEADER_CLOSE 01554 01555 //----------------------------------------------------------------------------// 01556 01557 #endif