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 00043 //----------------------------------------------------------------------------// 00044 00045 #include <sys/stat.h> 00046 #include <unistd.h> 00047 00048 #include <hdf5.h> 00049 #include <H5Epublic.h> 00050 00051 #include <boost/tokenizer.hpp> 00052 #include <boost/utility.hpp> 00053 00054 #include "Field3DFile.h" 00055 #include "Field.h" 00056 #include "ClassFactory.h" 00057 00058 00059 //----------------------------------------------------------------------------// 00060 00061 using namespace std; 00062 00063 //----------------------------------------------------------------------------// 00064 00065 FIELD3D_NAMESPACE_OPEN 00066 00067 //----------------------------------------------------------------------------// 00068 // Field3D namespaces 00069 //----------------------------------------------------------------------------// 00070 00071 using namespace Exc; 00072 using namespace Hdf5Util; 00073 using namespace File; 00074 00075 //----------------------------------------------------------------------------// 00076 // Local namespace 00077 //----------------------------------------------------------------------------// 00078 00079 namespace { 00080 00081 // Strings used only in this file -------------------------------------------- 00082 00083 const std::string k_mappingStr("mapping"); 00084 const std::string k_versionAttrName("version_number"); 00085 const std::string k_classNameAttrName("class_name"); 00086 const std::string k_mappingTypeAttrName("mapping_type"); 00087 00090 00091 int k_currentFileVersion[3] = 00092 { FIELD3D_MAJOR_VER, FIELD3D_MINOR_VER, FIELD3D_MICRO_VER }; 00093 int k_minFileVersion[2] = { 0, 0 }; 00094 00095 // Function objects used only in this file ----------------------------------- 00096 00097 std::vector<std::string> makeUnique(std::vector<std::string> vec) 00098 { 00099 std::vector<string> ret; 00100 std::sort(vec.begin(), vec.end()); 00101 std::vector<std::string>::iterator newEnd = 00102 std::unique(vec.begin(), vec.end()); 00103 ret.resize(std::distance(vec.begin(), newEnd)); 00104 std::copy(vec.begin(), newEnd, ret.begin()); 00105 return ret; 00106 } 00107 00108 //----------------------------------------------------------------------------// 00109 00111 template <class T> 00112 class print : std::unary_function<T, void> 00113 { 00114 public: 00115 print(int indentAmt) 00116 : indent(indentAmt) 00117 { } 00118 void operator()(const T& x) const 00119 { 00120 for (int i = 0; i < indent; i++) 00121 std::cout << " "; 00122 std::cout << x << std::endl; 00123 } 00124 int indent; 00125 }; 00126 00127 //----------------------------------------------------------------------------// 00128 00134 bool fileExists(const std::string &filename) 00135 { 00136 struct stat statbuf; 00137 return (stat(filename.c_str(), &statbuf) != -1); 00138 } 00139 00145 void checkFile(const std::string &filename) 00146 { 00147 if (!fileExists(filename)) 00148 { 00149 throw NoSuchFileException(filename); 00150 } 00151 } 00152 00153 //----------------------------------------------------------------------------// 00154 00155 bool isSupportedFileVersion(const int fileVersion[3], 00156 const int minVersion[2]) 00157 { 00158 stringstream currentVersionStr; 00159 currentVersionStr << k_currentFileVersion[0] << "." 00160 << k_currentFileVersion[1] << "." 00161 << k_currentFileVersion[2]; 00162 stringstream fileVersionStr; 00163 fileVersionStr << fileVersion[0] << "." 00164 << fileVersion[1] << "." 00165 << fileVersion[2]; 00166 stringstream minVersionStr; 00167 minVersionStr << minVersion[0] << "." 00168 << minVersion[1]; 00169 00170 if (fileVersion[0] > k_currentFileVersion[0] || 00171 (fileVersion[0] == k_currentFileVersion[0] && 00172 fileVersion[1] > k_currentFileVersion[1])) { 00173 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() + 00174 " is higher than the current version " + 00175 currentVersionStr.str()); 00176 return true; 00177 } 00178 00179 if (fileVersion[0] < minVersion[0] || 00180 (fileVersion[0] == minVersion[0] && 00181 fileVersion[1] < minVersion[1])) { 00182 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() + 00183 " is lower than the minimum supported version " + 00184 minVersionStr.str()); 00185 return false; 00186 } 00187 return true; 00188 } 00189 00190 //----------------------------------------------------------------------------// 00191 00192 static herr_t localPrintError( hid_t estack_id, void *stream ) 00193 { 00194 printf("H5E message -----------------------\n"); 00195 return H5Eprint2(estack_id, static_cast<FILE*>(stream)); 00196 } 00197 00198 //----------------------------------------------------------------------------// 00199 00200 } // end of local namespace 00201 00202 //----------------------------------------------------------------------------// 00203 // Partition implementations 00204 //----------------------------------------------------------------------------// 00205 00206 void 00207 Partition::addScalarLayer(const Layer &layer) 00208 { 00209 m_scalarLayers.push_back(layer); 00210 } 00211 00212 //----------------------------------------------------------------------------// 00213 00214 void 00215 Partition::addVectorLayer(const Layer &layer) 00216 { 00217 m_vectorLayers.push_back(layer); 00218 } 00219 00220 //----------------------------------------------------------------------------// 00221 00222 const Layer* 00223 Partition::scalarLayer(const std::string &name) const 00224 { 00225 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin(); 00226 i != m_scalarLayers.end(); ++i) { 00227 if (i->name == name) 00228 return &(*i); 00229 } 00230 return NULL; 00231 } 00232 00233 //----------------------------------------------------------------------------// 00234 00235 const Layer* 00236 Partition::vectorLayer(const std::string &name) const 00237 { 00238 for (VectorLayerList::const_iterator i = m_vectorLayers.begin(); 00239 i != m_vectorLayers.end(); ++i) { 00240 if (i->name == name) 00241 return &(*i); 00242 } 00243 return NULL; 00244 } 00245 00246 //----------------------------------------------------------------------------// 00247 00248 void 00249 Partition::getScalarLayerNames(std::vector<std::string> &names) const 00250 { 00251 // We don't want to do names.clear() here, since this gets called 00252 // inside some loops that want to accumulate names. 00253 for (ScalarLayerList::const_iterator i = m_scalarLayers.begin(); 00254 i != m_scalarLayers.end(); ++i) { 00255 names.push_back(i->name); 00256 } 00257 } 00258 00259 //----------------------------------------------------------------------------// 00260 00261 void 00262 Partition::getVectorLayerNames(std::vector<std::string> &names) const 00263 { 00264 // We don't want to do names.clear() here, since this gets called 00265 // inside some loops that want to accumulate names. 00266 for (VectorLayerList::const_iterator i = m_vectorLayers.begin(); 00267 i != m_vectorLayers.end(); ++i) { 00268 names.push_back(i->name); 00269 } 00270 } 00271 00272 //----------------------------------------------------------------------------// 00273 // Field3DFileBase implementations 00274 //----------------------------------------------------------------------------// 00275 00276 Field3DFileBase::Field3DFileBase() 00277 : m_file(-1), m_metadata(this) 00278 { 00279 // Suppressing HDF error messages 00280 // Explanation about the function for the error stack is here: 00281 // http://www.hdfgroup.org/HDF5/doc/RM/RM_H5E.html#Error-SetAuto2 00282 if (getenv("DEBUG_HDF")) { 00283 cerr << "Field3DFile -- HDF5 messages are on" << endl; 00284 H5Eset_auto(H5E_DEFAULT, localPrintError, NULL); 00285 } else { 00286 H5Eset_auto(H5E_DEFAULT, NULL, NULL); 00287 } 00288 } 00289 00290 //----------------------------------------------------------------------------// 00291 00292 Field3DFileBase::~Field3DFileBase() 00293 { 00294 close(); 00295 } 00296 00297 //----------------------------------------------------------------------------// 00298 00299 std::string 00300 Field3DFileBase::intPartitionName(const std::string &partitionName, 00301 const std::string &layerName, 00302 FieldRes::Ptr field) 00303 { 00304 // Loop over existing partitions and see if there's a matching mapping 00305 for (PartitionList::const_iterator i = m_partitions.begin(); 00306 i != m_partitions.end(); ++i) { 00307 if (removeUniqueId((**i).name) == partitionName) { 00308 if ((**i).mapping->isIdentical(field->mapping())) { 00309 return (**i).name; 00310 } 00311 } 00312 } 00313 00314 // If there was no previously matching name, then make a new one 00315 00316 int nextIdx = -1; 00317 if (m_partitionCount.find(partitionName) != m_partitionCount.end()) { 00318 nextIdx = ++m_partitionCount[partitionName]; 00319 } else { 00320 nextIdx = 0; 00321 m_partitionCount[partitionName] = 0; 00322 } 00323 00324 return makeIntPartitionName(partitionName, nextIdx); 00325 } 00326 00327 //----------------------------------------------------------------------------// 00328 00329 Partition::Ptr Field3DFileBase::partition(const string &partitionName) 00330 { 00331 for (PartitionList::iterator i = m_partitions.begin(); 00332 i != m_partitions.end(); ++i) { 00333 if ((**i).name == partitionName) 00334 return *i; 00335 } 00336 00337 return Partition::Ptr(); 00338 } 00339 00340 //----------------------------------------------------------------------------// 00341 00342 Partition::Ptr 00343 Field3DFileBase::partition(const string &partitionName) const 00344 { 00345 for (PartitionList::const_iterator i = m_partitions.begin(); 00346 i != m_partitions.end(); ++i) { 00347 if ((**i).name == partitionName) 00348 return *i; 00349 } 00350 00351 return Partition::Ptr(); 00352 } 00353 00354 //----------------------------------------------------------------------------// 00355 00356 std::string 00357 Field3DFileBase::removeUniqueId(const std::string &partitionName) const 00358 { 00359 size_t pos = partitionName.rfind("."); 00360 if (pos == partitionName.npos) { 00361 return partitionName; 00362 } else { 00363 return partitionName.substr(0, pos); 00364 } 00365 } 00366 00367 //----------------------------------------------------------------------------// 00368 00369 void 00370 Field3DFileBase::getPartitionNames(vector<string> &names) const 00371 { 00372 names.clear(); 00373 00374 vector<string> tempNames; 00375 00376 for (PartitionList::const_iterator i = m_partitions.begin(); 00377 i != m_partitions.end(); ++i) { 00378 tempNames.push_back(removeUniqueId((**i).name)); 00379 } 00380 00381 names = makeUnique(tempNames); 00382 } 00383 00384 //----------------------------------------------------------------------------// 00385 00386 void 00387 Field3DFileBase::getScalarLayerNames(vector<string> &names, 00388 const string &partitionName) const 00389 { 00390 names.clear(); 00391 00392 for (int i = 0; i < numIntPartitions(partitionName); i++) { 00393 string internalName = makeIntPartitionName(partitionName, i); 00394 Partition::Ptr part = partition(internalName); 00395 if (part) 00396 part->getScalarLayerNames(names); 00397 } 00398 00399 names = makeUnique(names); 00400 } 00401 00402 //----------------------------------------------------------------------------// 00403 00404 void 00405 Field3DFileBase::getVectorLayerNames(vector<string> &names, 00406 const string &partitionName) const 00407 { 00408 names.clear(); 00409 00410 for (int i = 0; i < numIntPartitions(partitionName); i++) { 00411 string internalName = makeIntPartitionName(partitionName, i); 00412 Partition::Ptr part = partition(internalName); 00413 if (part) 00414 part->getVectorLayerNames(names); 00415 } 00416 00417 names = makeUnique(names); 00418 } 00419 00420 //----------------------------------------------------------------------------// 00421 00422 void 00423 Field3DFileBase::getIntPartitionNames(vector<string> &names) const 00424 { 00425 names.clear(); 00426 00427 for (PartitionList::const_iterator i = m_partitions.begin(); 00428 i != m_partitions.end(); ++i) { 00429 names.push_back((**i).name); 00430 } 00431 } 00432 00433 //----------------------------------------------------------------------------// 00434 00435 void 00436 Field3DFileBase::getIntScalarLayerNames(vector<string> &names, 00437 const string &intPartitionName) const 00438 { 00439 names.clear(); 00440 00441 Partition::Ptr part = partition(intPartitionName); 00442 00443 if (!part) { 00444 Msg::print("getIntScalarLayerNames no partition: " + intPartitionName); 00445 return; 00446 } 00447 00448 part->getScalarLayerNames(names); 00449 } 00450 00451 //----------------------------------------------------------------------------// 00452 00453 void 00454 Field3DFileBase::getIntVectorLayerNames(vector<string> &names, 00455 const string &intPartitionName) const 00456 { 00457 names.clear(); 00458 00459 Partition::Ptr part = partition(intPartitionName); 00460 00461 if (!part) { 00462 Msg::print("getIntVectorLayerNames no partition: " + intPartitionName); 00463 return; 00464 } 00465 00466 part->getVectorLayerNames(names); 00467 } 00468 00469 //----------------------------------------------------------------------------// 00470 00471 void Field3DFileBase::clear() 00472 { 00473 closeInternal(); 00474 m_partitions.clear(); 00475 m_groupMembership.clear(); 00476 } 00477 00478 //----------------------------------------------------------------------------// 00479 00480 bool Field3DFileBase::close() 00481 { 00482 closeInternal(); 00483 00484 return true; 00485 } 00486 00487 //----------------------------------------------------------------------------// 00488 00489 void Field3DFileBase::closeInternal() 00490 { 00491 if (m_file != -1) { 00492 if (H5Fclose(m_file) < 0) { 00493 Msg::print(Msg::SevWarning, "Failed to close hdf5 file handle"); 00494 return; 00495 } 00496 m_file = -1; 00497 } 00498 } 00499 00500 //----------------------------------------------------------------------------// 00501 00502 int 00503 Field3DFileBase::numIntPartitions(const std::string &partitionName) const 00504 { 00505 int count = 0; 00506 00507 for (PartitionList::const_iterator i = m_partitions.begin(); 00508 i != m_partitions.end(); ++i) { 00509 string name = (**i).name; 00510 size_t pos = name.rfind("."); 00511 if (pos != name.npos) { 00512 if (name.substr(0, pos) == partitionName) { 00513 count++; 00514 } 00515 } 00516 } 00517 00518 return count; 00519 } 00520 00521 //----------------------------------------------------------------------------// 00522 00523 string 00524 Field3DFileBase::makeIntPartitionName(const std::string &partitionName, 00525 int i) const 00526 { 00527 return partitionName + "." + boost::lexical_cast<std::string>(i); 00528 } 00529 00530 //----------------------------------------------------------------------------// 00531 00532 void 00533 Field3DFileBase::addGroupMembership(const GroupMembershipMap& groupMembers) 00534 { 00535 GroupMembershipMap::const_iterator i= groupMembers.begin(); 00536 GroupMembershipMap::const_iterator end= groupMembers.end(); 00537 00538 for (; i != end; ++i) { 00539 GroupMembershipMap::iterator foundGroupIter = 00540 m_groupMembership.find(i->first); 00541 if (foundGroupIter != m_groupMembership.end()){ 00542 std::string value = m_groupMembership[i->first] + i->second; 00543 m_groupMembership[i->first] = value; 00544 } else { 00545 m_groupMembership[i->first] = i->second; 00546 } 00547 } 00548 } 00549 00550 //----------------------------------------------------------------------------// 00551 // Field3DInputFile implementations 00552 //----------------------------------------------------------------------------// 00553 00554 Field3DInputFile::Field3DInputFile() 00555 { 00556 // Empty 00557 } 00558 00559 //----------------------------------------------------------------------------// 00560 00561 Field3DInputFile::~Field3DInputFile() 00562 { 00563 clear(); 00564 } 00565 00566 //----------------------------------------------------------------------------// 00567 00568 bool Field3DInputFile::open(const string &filename) 00569 { 00570 clear(); 00571 00572 bool success = true; 00573 00574 m_filename = filename; 00575 00576 try { 00577 00578 string version; 00579 00580 // Throws exceptions if the file doesn't exist. 00581 // This was added because H5Fopen prints out a lot of junk 00582 // to the terminal. 00583 checkFile(filename); 00584 00585 m_file = H5Fopen(filename.c_str(), H5F_ACC_RDONLY, H5P_DEFAULT); 00586 00587 if (m_file < 0) 00588 throw NoSuchFileException(filename); 00589 00590 int fileVersion[3]; 00591 try { 00592 if (!readAttribute(m_file, k_versionAttrName, 3, fileVersion[0])) { 00593 //Msg::print(Msg::SevWarning, "Missing version_number attribute"); 00594 } else { 00595 if (!isSupportedFileVersion(fileVersion, k_minFileVersion)) { 00596 stringstream versionStr; 00597 versionStr << fileVersion[0] << "." 00598 << fileVersion[1] << "." 00599 << fileVersion[2]; 00600 throw UnsupportedVersionException(versionStr.str()); 00601 } 00602 } 00603 } 00604 catch (MissingAttributeException &e) { 00605 //Msg::print(Msg::SevWarning, "Missing version_number attribute"); 00606 } 00607 00608 try { 00609 if (H5Lexists(m_file, "field3d_global_metadata", H5P_DEFAULT)) { 00610 // read the metadata 00611 H5ScopedGopen metadataGroup(m_file, "field3d_global_metadata"); 00612 if (metadataGroup.id() > 0) { 00613 readMetadata(metadataGroup.id()); 00614 } 00615 } 00616 } 00617 catch (...) { 00618 Msg::print(Msg::SevWarning, 00619 "Unknown error when reading file metadata "); 00620 //throw BadFileHierarchyException(filename); 00621 } 00622 00623 try { 00624 if (!readPartitionAndLayerInfo()) { 00625 success = false; 00626 } 00627 } 00628 catch (MissingGroupException &e) { 00629 Msg::print(Msg::SevWarning, "Missing group: " + string(e.what())); 00630 throw BadFileHierarchyException(filename); 00631 } 00632 catch (ReadMappingException &e) { 00633 Msg::print(Msg::SevWarning, "Couldn't read mapping for partition: " 00634 + string(e.what())); 00635 throw BadFileHierarchyException(filename); 00636 } 00637 catch (Exception &e) { 00638 Msg::print(Msg::SevWarning, "Unknown error when reading file hierarchy: " 00639 + string(e.what())); 00640 throw BadFileHierarchyException(filename); 00641 } 00642 catch (...) { 00643 Msg::print(Msg::SevWarning, 00644 "Unknown error when reading file hierarchy. "); 00645 throw BadFileHierarchyException(filename); 00646 } 00647 00648 } 00649 catch (NoSuchFileException &e) { 00650 Msg::print(Msg::SevWarning, "Couldn't open file: " 00651 + string(e.what()) ); 00652 success = false; 00653 } 00654 catch (MissingAttributeException &e) { 00655 Msg::print(Msg::SevWarning, 00656 "In file: " + filename + " - " 00657 + string(e.what()) ); 00658 success = false; 00659 } 00660 catch (UnsupportedVersionException &e) { 00661 Msg::print(Msg::SevWarning, 00662 "In file: " + filename + " - File version can not be read: " 00663 + string(e.what())); 00664 success = false; 00665 } 00666 catch (BadFileHierarchyException &e) { 00667 Msg::print(Msg::SevWarning, 00668 "In file: " + filename + " - Bad file hierarchy. "); 00669 success = false; 00670 } 00671 catch (...) { 00672 Msg::print(Msg::SevWarning, 00673 "In file: " + filename + " Unknown exception "); 00674 success = false; 00675 } 00676 00677 if (!success) 00678 close(); 00679 00680 return success; 00681 } 00682 00683 //----------------------------------------------------------------------------// 00684 00685 bool Field3DInputFile::readPartitionAndLayerInfo() 00686 { 00687 using namespace InputFile; 00688 00689 // First, find the partitions --- 00690 00691 herr_t status; 00692 status = H5Literate(m_file, H5_INDEX_NAME, H5_ITER_NATIVE, NULL, 00693 &parsePartitions, this); 00694 00695 // Get the partition names to store 00696 m_partitions.clear(); 00697 00698 for (size_t i=0; i < m_partitionNames.size(); i++) { 00699 Partition::Ptr part(new Partition); 00700 part->name = m_partitionNames[i]; 00701 m_partitions.push_back(part); 00702 } 00703 00704 // For each partition, find its mapping --- 00705 00706 for (PartitionList::iterator i = m_partitions.begin(); 00707 i != m_partitions.end(); ++i) { 00708 00709 // Open the partition 00710 H5ScopedGopen partitionGroup(m_file, (**i).name); 00711 00712 string mappingPath = "/" + (**i).name + "/" + k_mappingStr; 00713 00714 // Open up the mapping group 00715 H5ScopedGopen mappingGroup(m_file, mappingPath); 00716 if (mappingGroup.id() < 0) 00717 throw MissingGroupException((**i).name + "/" + k_mappingStr); 00718 00719 // Try to build a mapping from it 00720 FieldMapping::Ptr mapping; 00721 00722 mapping = readFieldMapping(mappingGroup.id()); 00723 if (!mapping) { 00724 Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping"); 00725 throw ReadMappingException((**i).name); 00726 } 00727 00728 // Attach the mapping to the partition 00729 (**i).mapping = mapping; 00730 00731 } 00732 00733 // ... And then find its layers --- 00734 00735 for (PartitionList::const_iterator i = m_partitions.begin(); 00736 i != m_partitions.end(); ++i) { 00737 00738 // Open the partition 00739 H5ScopedGopen partitionGroup(m_file, (**i).name); 00740 00741 // Set up the info struct for the callback 00742 ParseLayersInfo info; 00743 info.file = this; 00744 info.partitionName = (**i).name; 00745 00746 m_layerInfo.clear(); 00747 00748 status = H5Literate(partitionGroup.id(), H5_INDEX_NAME, H5_ITER_NATIVE, 00749 NULL, &parseLayers, &info); 00750 00751 //set the layer information on the partitions here 00752 00753 for (std::vector<LayerInfo>::iterator i = m_layerInfo.begin(); 00754 i != m_layerInfo.end(); i++) { 00755 00756 std::string parent = i->parentName; 00757 00758 Partition::Ptr part = partition(parent); 00759 00760 Layer layer; 00761 layer.name = i->name; 00762 layer.parent = i->parentName; 00763 if (i->components == 1) { 00764 part->addScalarLayer(layer); 00765 } else if (i->components == 3) { 00766 part->addVectorLayer(layer); 00767 } 00768 } 00769 00770 } 00771 00772 return true; 00773 } 00774 00775 //----------------------------------------------------------------------------// 00776 00777 herr_t Field3DInputFile::parsePartition(hid_t loc_id, 00778 const std::string itemName) 00779 { 00780 // Add the partition --- 00781 00782 m_partitionNames.push_back(string(itemName)); 00783 return 0; 00784 } 00785 00786 //----------------------------------------------------------------------------// 00787 00791 herr_t Field3DInputFile::parseLayer(hid_t layerGroup, 00792 const std::string &partitionName, 00793 const std::string &layerName) 00794 { 00795 int components; 00796 if (!readAttribute(layerGroup, string("components"), 1, components)) { 00797 Msg::print(Msg::SevWarning, "Couldn't read components attribute for layer " 00798 + partitionName + "/" + layerName); 00799 return 0; 00800 } 00801 00802 LayerInfo linfo(partitionName,layerName,components); 00803 00804 m_layerInfo.push_back(linfo); 00805 00806 return 0; 00807 } 00808 00809 //----------------------------------------------------------------------------// 00810 00812 bool 00813 Field3DInputFile:: 00814 readMetadata(hid_t metadata_id, FieldBase::Ptr field) const 00815 { 00816 00817 hsize_t num_attrs = H5Aget_num_attrs(metadata_id); 00818 00819 if (num_attrs > 0) { 00820 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 00821 H5ScopedAopenIdx attrIdx(metadata_id, idx); 00822 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 00823 if (len > 0) { 00824 char *name = new char[len+1]; 00825 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 00826 H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT); 00827 H5ScopedAget_space attrSpace(attr); 00828 H5ScopedAget_type attrType(attr); 00829 H5T_class_t typeClass = H5Tget_class(attrType); 00830 00831 if (typeClass == H5T_STRING) { 00832 string value; 00833 if (!readAttribute(metadata_id, name, value)) { 00834 Msg::print(Msg::SevWarning, 00835 "Failed to read metadata " + string(name)); 00836 if (name) { 00837 delete[] name; 00838 } 00839 continue; 00840 } 00841 field->metadata().setStrMetadata(name, value); 00842 00843 } 00844 else { 00845 00846 if (H5Sget_simple_extent_ndims(attrSpace) != 1) { 00847 Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 00848 + string(name)); 00849 if (name) { 00850 delete[] name; 00851 } 00852 continue; 00853 } 00854 00855 hsize_t dims[1]; 00856 H5Sget_simple_extent_dims(attrSpace, dims, NULL); 00857 00858 if (typeClass == H5T_INTEGER) { 00859 if (dims[0] == 1){ 00860 int value; 00861 if (!readAttribute(metadata_id, name, dims[0], value)) 00862 Msg::print(Msg::SevWarning, "Failed to read metadata " 00863 + string(name)); 00864 field->metadata().setIntMetadata(name, value); 00865 } 00866 else if (dims[0] == 3){ 00867 V3i value; 00868 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00869 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00870 string(name) ); 00871 field->metadata().setVecIntMetadata(name, value); 00872 } 00873 else { 00874 Msg::print(Msg::SevWarning, 00875 "Attribute of size " + 00876 boost::lexical_cast<std::string>(dims[0]) 00877 + " is not valid for metadata"); 00878 } 00879 } 00880 else if (typeClass == H5T_FLOAT) { 00881 if (dims[0] == 1){ 00882 float value; 00883 if (!readAttribute(metadata_id, name, dims[0], value)) 00884 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00885 string(name) ); 00886 00887 field->metadata().setFloatMetadata(name, value); 00888 } 00889 else if (dims[0] == 3){ 00890 V3f value; 00891 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00892 Msg::print(Msg::SevWarning, "Failed to read metadata "+ 00893 string(name) ); 00894 field->metadata().setVecFloatMetadata(name, value); 00895 } 00896 else { 00897 Msg::print(Msg::SevWarning, "Attribute of size " + 00898 boost::lexical_cast<std::string>(dims[0]) + 00899 " is not valid for metadata"); 00900 } 00901 } 00902 else { 00903 Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 00904 + "' has unsupported data type for metadata"); 00905 00906 } 00907 } 00908 } 00909 if (name) { 00910 delete[] name; 00911 } 00912 } 00913 } 00914 } 00915 00916 return true; 00917 } 00918 00919 //----------------------------------------------------------------------------// 00920 00922 bool 00923 Field3DInputFile::readMetadata(hid_t metadata_id) 00924 { 00925 00926 hsize_t num_attrs = H5Aget_num_attrs(metadata_id); 00927 00928 if (num_attrs > 0) { 00929 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 00930 H5ScopedAopenIdx attrIdx(metadata_id, idx); 00931 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 00932 if (len > 0) { 00933 char *name = new char[len+1]; 00934 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 00935 H5ScopedAopen attr(metadata_id, name, H5P_DEFAULT); 00936 H5ScopedAget_space attrSpace(attr); 00937 H5ScopedAget_type attrType(attr); 00938 H5T_class_t typeClass = H5Tget_class(attrType); 00939 00940 if (typeClass == H5T_STRING) { 00941 string value; 00942 if (!readAttribute(metadata_id, name, value)) { 00943 Msg::print(Msg::SevWarning, 00944 "Failed to read metadata " + string(name)); 00945 if (name) { 00946 delete[] name; 00947 } 00948 continue; 00949 } 00950 metadata().setStrMetadata(name, value); 00951 00952 } 00953 else { 00954 00955 if (H5Sget_simple_extent_ndims(attrSpace) != 1) { 00956 Msg::print(Msg::SevWarning, "Bad attribute rank for attribute " 00957 + string(name)); 00958 if (name) { 00959 delete[] name; 00960 } 00961 continue; 00962 } 00963 00964 hsize_t dims[1]; 00965 H5Sget_simple_extent_dims(attrSpace, dims, NULL); 00966 00967 if (typeClass == H5T_INTEGER) { 00968 if (dims[0] == 1){ 00969 int value; 00970 if (!readAttribute(metadata_id, name, dims[0], value)) 00971 Msg::print(Msg::SevWarning, "Failed to read metadata " 00972 + string(name)); 00973 metadata().setIntMetadata(name, value); 00974 } 00975 else if (dims[0] == 3){ 00976 V3i value; 00977 if (!readAttribute(metadata_id, name, dims[0], value.x)) 00978 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00979 string(name) ); 00980 metadata().setVecIntMetadata(name, value); 00981 } 00982 else { 00983 Msg::print(Msg::SevWarning, 00984 "Attribute of size " + 00985 boost::lexical_cast<std::string>(dims[0]) 00986 + " is not valid for metadata"); 00987 } 00988 } 00989 else if (typeClass == H5T_FLOAT) { 00990 if (dims[0] == 1){ 00991 float value; 00992 if (!readAttribute(metadata_id, name, dims[0], value)) 00993 Msg::print(Msg::SevWarning, "Failed to read metadata " + 00994 string(name) ); 00995 00996 metadata().setFloatMetadata(name, value); 00997 } 00998 else if (dims[0] == 3){ 00999 V3f value; 01000 if (!readAttribute(metadata_id, name, dims[0], value.x)) 01001 Msg::print(Msg::SevWarning, "Failed to read metadata "+ 01002 string(name) ); 01003 metadata().setVecFloatMetadata(name, value); 01004 } 01005 else { 01006 Msg::print(Msg::SevWarning, "Attribute of size " + 01007 boost::lexical_cast<std::string>(dims[0]) + 01008 " is not valid for metadata"); 01009 } 01010 } 01011 else { 01012 Msg::print(Msg::SevWarning, "Attribute '" + string(name) + 01013 + "' has unsupported data type for metadata"); 01014 01015 } 01016 } 01017 } 01018 if (name) { 01019 delete[] name; 01020 } 01021 } 01022 } 01023 } 01024 01025 return true; 01026 } 01027 01028 //----------------------------------------------------------------------------// 01029 01030 bool 01031 Field3DInputFile:: 01032 readGroupMembership(GroupMembershipMap &gpMembershipMap) 01033 { 01034 if (!H5Lexists(m_file, "field3d_group_membership", H5P_DEFAULT)) { 01035 return false; 01036 } 01037 01038 H5ScopedGopen memberGroup(m_file, "field3d_group_membership"); 01039 if (memberGroup < 0) { 01040 return false; 01041 } 01042 01043 typedef boost::tokenizer<boost::char_separator<char> > Tok; 01044 01045 hsize_t num_attrs = H5Aget_num_attrs(memberGroup); 01046 if (num_attrs > 0) { 01047 01048 for (hsize_t idx=0; idx < num_attrs ; ++idx) { 01049 H5ScopedAopenIdx attrIdx(memberGroup, idx); 01050 size_t len = H5Aget_name(attrIdx.id(), 0, NULL); 01051 if (len>0) { 01052 char *name = new char[len+1]; 01053 if (H5Aget_name(attrIdx.id(), len+1, name) > 0) { 01054 01055 if (string(name) == "is_field3d_group_membership") 01056 continue; 01057 01058 H5ScopedAopen attr(memberGroup, name, H5P_DEFAULT); 01059 H5ScopedAget_space attrSpace(attr); 01060 H5ScopedAget_type attrType(attr); 01061 H5T_class_t typeClass = H5Tget_class(attrType); 01062 01063 if (typeClass == H5T_STRING) { 01064 string value; 01065 if (!readAttribute(memberGroup, name, value)) { 01066 Msg::print(Msg::SevWarning, 01067 "Failed to read group membership data " 01068 + string(name)); 01069 continue; 01070 } 01071 01072 { 01073 boost::char_separator<char> sep(" :"); 01074 Tok tok(value, sep); 01075 string new_value; 01076 for(Tok::iterator beg=tok.begin(); beg!=tok.end();){ 01077 01078 string fieldgroup = *beg; ++beg; 01079 fieldgroup = removeUniqueId(fieldgroup) + ":" + *beg; ++beg; 01080 new_value += fieldgroup + " "; 01081 } 01082 01083 m_groupMembership[name] = value; 01084 gpMembershipMap[name] = new_value; 01085 } 01086 } 01087 } 01088 } 01089 } 01090 } 01091 01092 return true; 01093 } 01094 01095 01096 //----------------------------------------------------------------------------// 01097 // Field3DFile-related callback functions 01098 //----------------------------------------------------------------------------// 01099 01100 namespace InputFile { 01101 01102 //----------------------------------------------------------------------------// 01103 01104 herr_t parsePartitions(hid_t loc_id, const char *itemName, 01105 const H5L_info_t *linfo, void *opdata) 01106 { 01107 herr_t status; 01108 H5O_info_t infobuf; 01109 01110 status = H5Oget_info_by_name(loc_id, itemName, &infobuf, H5P_DEFAULT); 01111 01112 if (status < 0) { 01113 return -1; 01114 } 01115 01116 if (infobuf.type == H5O_TYPE_GROUP) { 01117 01118 // Check that we have a name 01119 if (!itemName) { 01120 return -1; 01121 } 01122 01123 // check that this group is not "groupMembership" 01124 if (string(itemName) != "field3d_group_membership" && 01125 string(itemName) != "field3d_global_metadata") 01126 { 01127 01128 // Get a pointer to the file data structure 01129 Field3DInputFile* fileObject = static_cast<Field3DInputFile*>(opdata); 01130 if (!fileObject) { 01131 return -1; 01132 } 01133 01134 return fileObject->parsePartition(loc_id, itemName); 01135 } 01136 } 01137 return 0; 01138 } 01139 01140 //----------------------------------------------------------------------------// 01141 01142 herr_t parseLayers(hid_t loc_id, const char *itemName, 01143 const H5L_info_t *linfo, void *opdata) 01144 { 01145 herr_t status; 01146 H5O_info_t infobuf; 01147 01148 status = H5Oget_info_by_name (loc_id, itemName, &infobuf, H5P_DEFAULT); 01149 01150 if (infobuf.type == H5O_TYPE_GROUP) { 01151 01152 // Check that we have a name 01153 if (!itemName) 01154 return -1; 01155 01156 // Get a pointer to the file data structure 01157 ParseLayersInfo* info = static_cast<ParseLayersInfo*>(opdata); 01158 if (!info) 01159 return -1; 01160 01161 // Open up the layer group 01162 H5ScopedGopen layerGroup(loc_id, itemName); 01163 01164 // Check if it's a layer 01165 string classType; 01166 try { 01167 if (!readAttribute(layerGroup.id(), "class_type", classType)) { 01168 return 0; 01169 } 01170 if (classType == string("field3d_layer")) 01171 return info->file->parseLayer(layerGroup.id(), info->partitionName, 01172 itemName); 01173 01174 } 01175 catch (MissingAttributeException &e) { 01176 01177 } 01178 return 0; 01179 01180 } 01181 01182 return 0; 01183 } 01184 01185 //----------------------------------------------------------------------------// 01186 01187 } // namespace InputFile 01188 01189 //----------------------------------------------------------------------------// 01190 // Field3DOutputFile implementations 01191 //----------------------------------------------------------------------------// 01192 01193 Field3DOutputFile::Field3DOutputFile() 01194 { 01195 // Empty 01196 } 01197 01198 //----------------------------------------------------------------------------// 01199 01200 Field3DOutputFile::~Field3DOutputFile() 01201 { 01202 01203 } 01204 01205 //----------------------------------------------------------------------------// 01206 01209 bool Field3DOutputFile::create(const string &filename, CreateMode cm) 01210 { 01211 closeInternal(); 01212 01213 bool success = true; 01214 01215 try { 01216 01217 hid_t faid = H5Pcreate(H5P_FILE_ACCESS); 01218 H5Pset_libver_bounds(faid, H5F_LIBVER_LATEST, H5F_LIBVER_LATEST); 01219 01220 // Create new file 01221 switch (cm) { 01222 case OverwriteMode: 01223 m_file = H5Fcreate(filename.c_str(), 01224 H5F_ACC_TRUNC, H5P_DEFAULT, faid); 01225 break; 01226 case FailOnExisting: 01227 m_file = H5Fcreate(filename.c_str(), 01228 H5F_ACC_EXCL, H5P_DEFAULT, faid); 01229 break; 01230 } 01231 01232 // Check that file was created 01233 if (m_file < 0) 01234 throw ErrorCreatingFileException(filename); 01235 01236 // Create a version attribute on the root node 01237 if (!writeAttribute(m_file, k_versionAttrName, 3, 01238 k_currentFileVersion[0])) { 01239 Msg::print(Msg::SevWarning, "Adding version number."); 01240 closeInternal(); 01241 return false; 01242 } 01243 01244 } 01245 catch (ErrorCreatingFileException &e) { 01246 Msg::print(Msg::SevWarning, "Couldn't create file: " + string(e.what()) ); 01247 success = false; 01248 } 01249 catch (WriteAttributeException &e) { 01250 Msg::print(Msg::SevWarning, "In file : " + filename + 01251 " - Couldn't add attribute " + string(e.what()) ); 01252 success = false; 01253 } 01254 catch (...) { 01255 Msg::print(Msg::SevWarning, 01256 "Unknown error when creating file: " + filename ); 01257 success = false; 01258 } 01259 01260 return success; 01261 } 01262 01263 //----------------------------------------------------------------------------// 01264 01265 bool Field3DOutputFile::writeMapping(hid_t partitionGroup, 01266 FieldMapping::Ptr mapping) 01267 { 01268 try { 01269 // Make a group under the partition to store the mapping data 01270 H5ScopedGcreate mappingGroup(partitionGroup, k_mappingStr); 01271 if (mappingGroup.id() < 0) 01272 throw CreateGroupException(k_mappingStr); 01273 // Let FieldMappingIO handle the rest 01274 if (!writeFieldMapping(mappingGroup.id(), mapping)) 01275 throw WriteMappingException(k_mappingStr); 01276 } 01277 catch (CreateGroupException &e) { 01278 Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) ); 01279 throw WriteMappingException(k_mappingStr); 01280 } 01281 return true; 01282 } 01283 01284 //----------------------------------------------------------------------------// 01285 01286 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup, FieldBase::Ptr field) 01287 { 01288 using namespace Hdf5Util; 01289 01290 { 01291 FieldMetadata<FieldBase>::StrMetadata::const_iterator i = 01292 field->metadata().strMetadata().begin(); 01293 FieldMetadata<FieldBase>::StrMetadata::const_iterator end = 01294 field->metadata().strMetadata().end(); 01295 for (; i != end; ++i) { 01296 if (!writeAttribute(metadataGroup, i->first, i->second)) 01297 { 01298 Msg::print(Msg::SevWarning, "Writing attribute " + i->first ); 01299 return false; 01300 } 01301 } 01302 } 01303 01304 { 01305 FieldMetadata<FieldBase>::IntMetadata::const_iterator i = 01306 field->metadata().intMetadata().begin(); 01307 FieldMetadata<FieldBase>::IntMetadata::const_iterator end = 01308 field->metadata().intMetadata().end(); 01309 for (; i != end; ++i) { 01310 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01311 { 01312 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01313 return false; 01314 } 01315 } 01316 } 01317 01318 { 01319 FieldMetadata<FieldBase>::FloatMetadata::const_iterator i = 01320 field->metadata().floatMetadata().begin(); 01321 FieldMetadata<FieldBase>::FloatMetadata::const_iterator end = 01322 field->metadata().floatMetadata().end(); 01323 for (; i != end; ++i) { 01324 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01325 { 01326 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01327 return false; 01328 } 01329 } 01330 } 01331 01332 { 01333 FieldMetadata<FieldBase>::VecIntMetadata::const_iterator i = 01334 field->metadata().vecIntMetadata().begin(); 01335 FieldMetadata<FieldBase>::VecIntMetadata::const_iterator end = 01336 field->metadata().vecIntMetadata().end(); 01337 for (; i != end; ++i) { 01338 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01339 { 01340 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01341 return false; 01342 } 01343 } 01344 } 01345 01346 { 01347 FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator i = 01348 field->metadata().vecFloatMetadata().begin(); 01349 FieldMetadata<FieldBase>::VecFloatMetadata::const_iterator end = 01350 field->metadata().vecFloatMetadata().end(); 01351 for (; i != end; ++i) { 01352 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01353 { 01354 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01355 return false; 01356 } 01357 } 01358 01359 } 01360 01361 return true; 01362 01363 } 01364 01365 //----------------------------------------------------------------------------// 01366 01367 bool Field3DOutputFile::writeMetadata(hid_t metadataGroup) 01368 { 01369 using namespace Hdf5Util; 01370 01371 { 01372 FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator i = 01373 metadata().strMetadata().begin(); 01374 FieldMetadata<Field3DFileBase>::StrMetadata::const_iterator end = 01375 metadata().strMetadata().end(); 01376 for (; i != end; ++i) { 01377 if (!writeAttribute(metadataGroup, i->first, i->second)) 01378 { 01379 Msg::print(Msg::SevWarning, "Writing attribute " + i->first ); 01380 return false; 01381 } 01382 } 01383 } 01384 01385 { 01386 FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator i = 01387 metadata().intMetadata().begin(); 01388 FieldMetadata<Field3DFileBase>::IntMetadata::const_iterator end = 01389 metadata().intMetadata().end(); 01390 for (; i != end; ++i) { 01391 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01392 { 01393 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01394 return false; 01395 } 01396 } 01397 } 01398 01399 { 01400 FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator i = 01401 metadata().floatMetadata().begin(); 01402 FieldMetadata<Field3DFileBase>::FloatMetadata::const_iterator end = 01403 metadata().floatMetadata().end(); 01404 for (; i != end; ++i) { 01405 if (!writeAttribute(metadataGroup, i->first, 1, i->second)) 01406 { 01407 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01408 return false; 01409 } 01410 } 01411 } 01412 01413 { 01414 FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator i = 01415 metadata().vecIntMetadata().begin(); 01416 FieldMetadata<Field3DFileBase>::VecIntMetadata::const_iterator end = 01417 metadata().vecIntMetadata().end(); 01418 for (; i != end; ++i) { 01419 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01420 { 01421 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01422 return false; 01423 } 01424 } 01425 } 01426 01427 { 01428 FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator i = 01429 metadata().vecFloatMetadata().begin(); 01430 FieldMetadata<Field3DFileBase>::VecFloatMetadata::const_iterator end = 01431 metadata().vecFloatMetadata().end(); 01432 for (; i != end; ++i) { 01433 if (!writeAttribute(metadataGroup, i->first, 3, i->second.x)) 01434 { 01435 Msg::print(Msg::SevWarning, "Writing attribute " + i->first); 01436 return false; 01437 } 01438 } 01439 01440 } 01441 01442 return true; 01443 01444 } 01445 01446 //----------------------------------------------------------------------------// 01447 01448 bool 01449 Field3DOutputFile::writeGlobalMetadata() 01450 { 01451 01452 // Add metadata group and write it out 01453 H5ScopedGcreate metadataGroup(m_file, "field3d_global_metadata"); 01454 if (metadataGroup.id() < 0) { 01455 Msg::print(Msg::SevWarning, "Error creating group: file metadata"); 01456 return false; 01457 } 01458 if (!writeMetadata(metadataGroup.id())) { 01459 Msg::print(Msg::SevWarning, "Error writing file metadata."); 01460 return false; 01461 } 01462 01463 return true; 01464 } 01465 01466 //----------------------------------------------------------------------------// 01467 01468 bool 01469 Field3DOutputFile::writeGroupMembership() 01470 { 01471 using namespace std; 01472 using namespace Hdf5Util; 01473 01474 if (!m_groupMembership.size()) 01475 return true; 01476 01477 H5ScopedGcreate group(m_file, "field3d_group_membership"); 01478 if (group < 0) { 01479 Msg::print(Msg::SevWarning, 01480 "Error creating field3d_group_membership group."); 01481 return false; 01482 } 01483 01484 if (!writeAttribute(group, "is_field3d_group_membership", "1")) { 01485 Msg::print(Msg::SevWarning, 01486 "Failed to write field3d_group_membership attribute."); 01487 return false; 01488 } 01489 01490 std::map<std::string, std::string>::const_iterator iter = 01491 m_groupMembership.begin(); 01492 std::map<std::string, std::string>::const_iterator iEnd = 01493 m_groupMembership.end(); 01494 01495 for (; iter != iEnd; ++iter) { 01496 if (!writeAttribute(group, iter->first, iter->second)) { 01497 Msg::print(Msg::SevWarning, 01498 "Failed to write groupMembership string: "+ iter->first); 01499 return false; 01500 } 01501 } 01502 01503 return true; 01504 } 01505 01506 //----------------------------------------------------------------------------// 01507 // Debug 01508 //----------------------------------------------------------------------------// 01509 01510 void Field3DFileBase::printHierarchy() const 01511 { 01512 // For each partition 01513 for (PartitionList::const_iterator i = m_partitions.begin(); 01514 i != m_partitions.end(); ++i) { 01515 cout << "Name: " << (**i).name << endl; 01516 if ((**i).mapping) 01517 cout << " Mapping: " << (**i).mapping->className() << endl; 01518 else 01519 cout << " Mapping: NULL" << endl; 01520 cout << " Scalar layers: " << endl; 01521 vector<string> sNames; 01522 (**i).getScalarLayerNames(sNames); 01523 for_each(sNames.begin(), sNames.end(), print<string>(4)); 01524 cout << " Vector layers: " << endl; 01525 vector<string> vNames; 01526 (**i).getVectorLayerNames(vNames); 01527 for_each(vNames.begin(), vNames.end(), print<string>(4)); 01528 } 01529 } 01530 01531 //----------------------------------------------------------------------------// 01532 // Function Implementations 01533 //----------------------------------------------------------------------------// 01534 01535 bool writeField(hid_t layerGroup, FieldBase::Ptr field) 01536 { 01537 ClassFactory &factory = ClassFactory::singleton(); 01538 01539 FieldIO::Ptr io = factory.createFieldIO(field->className()); 01540 assert(io != 0); 01541 if (!io) { 01542 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01543 field->className()); 01544 return false; 01545 } 01546 01547 // Add class name attribute 01548 if (!writeAttribute(layerGroup, k_classNameAttrName, 01549 field->className())) { 01550 Msg::print(Msg::SevWarning, "Error adding class name attribute."); 01551 return false; 01552 } 01553 01554 return io->write(layerGroup, field); 01555 } 01556 01557 //----------------------------------------------------------------------------// 01558 01559 FieldMapping::Ptr readFieldMapping(hid_t mappingGroup) 01560 { 01561 ClassFactory &factory = ClassFactory::singleton(); 01562 01563 std::string className; 01564 01565 if (!readAttribute(mappingGroup, k_mappingTypeAttrName, className)) { 01566 Msg::print(Msg::SevWarning, "Couldn't find " + k_mappingTypeAttrName + 01567 " attribute"); 01568 return FieldMapping::Ptr(); 01569 } 01570 01571 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className); 01572 assert(io != 0); 01573 if (!io) { 01574 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01575 className); 01576 return FieldMapping::Ptr(); 01577 } 01578 01579 01580 FieldMapping::Ptr mapping = io->read(mappingGroup); 01581 if (!mapping) { 01582 Msg::print(Msg::SevWarning, "Couldn't read mapping"); 01583 return FieldMapping::Ptr(); 01584 } 01585 01586 return mapping; 01587 } 01588 01589 //----------------------------------------------------------------------------// 01590 01591 bool writeFieldMapping(hid_t mappingGroup, FieldMapping::Ptr mapping) 01592 { 01593 ClassFactory &factory = ClassFactory::singleton(); 01594 01595 std::string className = mapping->className(); 01596 01597 if (!writeAttribute(mappingGroup, k_mappingTypeAttrName, className)) { 01598 Msg::print(Msg::SevWarning, "Couldn't add " + className + " attribute"); 01599 return false; 01600 } 01601 01602 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className); 01603 assert(io != 0); 01604 if (!io) { 01605 Msg::print(Msg::SevWarning, "Unable to find class type: " + 01606 className); 01607 return false; 01608 } 01609 01610 return io->write(mappingGroup, mapping); 01611 } 01612 01613 //----------------------------------------------------------------------------// 01614 01615 FIELD3D_NAMESPACE_SOURCE_CLOSE 01616 01617 //----------------------------------------------------------------------------//