Field3D
Field3DFile.cpp
Go to the documentation of this file.
1//----------------------------------------------------------------------------//
2
3/*
4 * Copyright (c) 2014 Sony Pictures Imageworks Inc.,
5 * Pixar Animation Studios Inc.
6 *
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 *
13 * Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the
18 * distribution. Neither the name of Sony Pictures Imageworks nor the
19 * names of its contributors may be used to endorse or promote
20 * products derived from this software without specific prior written
21 * permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27 * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
29 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
30 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
32 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
34 * OF THE POSSIBILITY OF SUCH DAMAGE.
35 */
36
37//----------------------------------------------------------------------------//
38
44//----------------------------------------------------------------------------//
45
46#include "Field3DFile.h"
47
48#include <sys/stat.h>
49#ifndef WIN32
50#include <unistd.h>
51#endif
52
53#include <boost/tokenizer.hpp>
54#include <boost/utility.hpp>
55
56#include "Field.h"
57#include "FieldCache.h"
58#include "Field3DFileHDF5.h"
59#include "ClassFactory.h"
60#include "OArchive.h"
61#include "OgIAttribute.h"
62#include "OgIDataset.h"
63#include "OgIGroup.h"
64#include "OgOAttribute.h"
65#include "OgODataset.h"
66#include "OgOGroup.h"
67
68//----------------------------------------------------------------------------//
69
70using namespace std;
71
72//----------------------------------------------------------------------------//
73
75
76//----------------------------------------------------------------------------//
77// Field3D namespaces
78//----------------------------------------------------------------------------//
79
80using namespace Exc;
81
82//----------------------------------------------------------------------------//
83// Local namespace
84//----------------------------------------------------------------------------//
85
86namespace {
87
88 // Strings used only in this file --------------------------------------------
89
90 const std::string k_mappingStr("mapping");
91 const std::string k_partitionName("partition");
92 const std::string k_versionAttrName("version_number");
93 const std::string k_classNameAttrName("class_name");
94 const std::string k_mappingTypeAttrName("mapping_type");
95
98
102 int k_minFileVersion[2] = { 0, 0 };
103
104 // Function objects used only in this file -----------------------------------
105
106 std::vector<std::string> makeUnique(std::vector<std::string> vec)
107 {
108 std::vector<string> ret;
109 std::sort(vec.begin(), vec.end());
110 std::vector<std::string>::iterator newEnd =
111 std::unique(vec.begin(), vec.end());
112 ret.resize(std::distance(vec.begin(), newEnd));
113 std::copy(vec.begin(), newEnd, ret.begin());
114 return ret;
115 }
116
117 //--------------------------------------------------------------------------//
118
120 template <class T>
121 class print : std::unary_function<T, void>
122 {
123 public:
124 print(int indentAmt)
125 : indent(indentAmt)
126 { }
127 void operator()(const T& x) const
128 {
129 for (int i = 0; i < indent; i++)
130 std::cout << " ";
131 std::cout << x << std::endl;
132 }
133 int indent;
134 };
135
136 //--------------------------------------------------------------------------//
137
143 void checkFile(const std::string &filename)
144 {
145 if (!fileExists(filename))
146 {
147 throw NoSuchFileException(filename);
148 }
149 }
150
151 //--------------------------------------------------------------------------//
152
153 bool isSupportedFileVersion(const int fileVersion[3],
154 const int minVersion[2])
155 {
158 << k_currentFileVersion[1] << "."
161 fileVersionStr << fileVersion[0] << "."
162 << fileVersion[1] << "."
163 << fileVersion[2];
165 minVersionStr << minVersion[0] << "."
166 << minVersion[1];
167
168 if (fileVersion[0] > k_currentFileVersion[0] ||
171 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
172 " is higher than the current version " +
173 currentVersionStr.str());
174 return true;
175 }
176
177 if (fileVersion[0] < minVersion[0] ||
178 (fileVersion[0] == minVersion[0] &&
179 fileVersion[1] < minVersion[1])) {
180 Msg::print(Msg::SevWarning, "File version " + fileVersionStr.str() +
181 " is lower than the minimum supported version " +
182 minVersionStr.str());
183 return false;
184 }
185 return true;
186 }
187
191 {
193
195 mappingGroup.findAttribute<string>(k_mappingTypeAttrName);
196 if (!mappingAttr.isValid()) {
198 " attribute");
199 return FieldMapping::Ptr();
200 }
201 const std::string className = mappingAttr.value();
202
203 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
204 assert(io != 0);
205 if (!io) {
206 Msg::print(Msg::SevWarning, "Unable to find class type: " + className);
207 return FieldMapping::Ptr();
208 }
209
210 FieldMapping::Ptr mapping = io->read(mappingGroup);
211 if (!mapping) {
212 Msg::print(Msg::SevWarning, "Couldn't read mapping");
213 return FieldMapping::Ptr();
214 }
215
216 return mapping;
217 }
218
219 //--------------------------------------------------------------------------//
220
224 {
226
227 FieldIO::Ptr io = factory.createFieldIO(field->className());
228 assert(io != 0);
229 if (!io) {
230 Msg::print(Msg::SevWarning, "Unable to find class type: " +
231 field->className());
232 return false;
233 }
234
235 // Add class name attribute
237
238 return io->write(layerGroup, field);
240 return false;
241 }
242
243 //--------------------------------------------------------------------------//
244
247 template <class Data_T>
248 typename Field<Data_T>::Ptr
249 readField(const std::string &className, const OgIGroup &layerGroup,
250 const std::string &filename, const std::string &layerPath)
251 {
253
254 typedef typename Field<Data_T>::Ptr FieldPtr;
255
256 FieldIO::Ptr io = factory.createFieldIO(className);
257 if (!io) {
258 Msg::print(Msg::SevWarning, "Unable to find class type: " +
259 className);
260 return FieldPtr();
261 }
262
263 OgDataType typeEnum = OgawaTypeTraits<Data_T>::typeEnum();
264 FieldBase::Ptr field = io->read(layerGroup, filename, layerPath, typeEnum);
265
266 if (!field) {
267 // We don't need to print a message, because it could just be that
268 // a layer of the specified data type and name couldn't be found
269 return FieldPtr();
270 }
271
272 FieldPtr result = field_dynamic_cast<Field<Data_T> >(field);
273
274 if (result) {
275 return result;
276 }
277
278 return FieldPtr();
279 }
280
281 //--------------------------------------------------------------------------//
282
283 bool readMeta(const OgIGroup &group, FieldMetadata &metadata)
284 {
285 // Grab all the attribute names
286 std::vector<std::string> attrs = group.attributeNames();
287 // Loop over attribute names and test types
288 for (size_t i = 0, end = attrs.size(); i < end; ++i) {
289 // String metadata
290 {
291 OgIAttribute<string> attr = group.findAttribute<string>(attrs[i]);
292 if (attr.isValid()) {
293 metadata.setStrMetadata(attrs[i], attr.value());
294 }
295 }
296 // Int metadata
297 {
298 OgIAttribute<int> attr = group.findAttribute<int>(attrs[i]);
299 if (attr.isValid()) {
300 metadata.setIntMetadata(attrs[i], attr.value());
301 }
302 }
303 // Float metadata
304 {
305 OgIAttribute<float> attr = group.findAttribute<float>(attrs[i]);
306 if (attr.isValid()) {
307 metadata.setFloatMetadata(attrs[i], attr.value());
308 }
309 }
310 // VecInt metadata
311 {
312 OgIAttribute<veci32_t> attr = group.findAttribute<veci32_t>(attrs[i]);
313 if (attr.isValid()) {
314 metadata.setVecIntMetadata(attrs[i], attr.value());
315 }
316 }
317 // VecFloat metadata
318 {
319 OgIAttribute<vec32_t> attr = group.findAttribute<vec32_t>(attrs[i]);
320 if (attr.isValid()) {
321 metadata.setVecFloatMetadata(attrs[i], attr.value());
322 }
323 }
324 }
325
326 return true;
327 }
328
329 //--------------------------------------------------------------------------//
330
331} // end of local namespace
332
333//----------------------------------------------------------------------------//
334// File namespace
335//----------------------------------------------------------------------------//
336
337namespace File {
338
339//----------------------------------------------------------------------------//
340// Partition implementations
341//----------------------------------------------------------------------------//
342
343std::string Partition::className() const
344{
345 return k_partitionName;
346}
347
348//----------------------------------------------------------------------------//
349
350void
352{
353 m_layers.push_back(layer);
354}
355
356//----------------------------------------------------------------------------//
357
358const Layer*
359Partition::layer(const std::string &name) const
360{
361 for (LayerList::const_iterator i = m_layers.begin();
362 i != m_layers.end(); ++i) {
363 if (i->name == name) {
364 return &(*i);
365 }
366 }
367 return NULL;
368}
369
370//----------------------------------------------------------------------------//
371
372void
373Partition::getLayerNames(std::vector<std::string> &names) const
374{
375 // We don't want to do names.clear() here, since this gets called
376 // inside some loops that want to accumulate names.
377 for (LayerList::const_iterator i = m_layers.begin();
378 i != m_layers.end(); ++i) {
379 names.push_back(i->name);
380 }
381}
382
383//----------------------------------------------------------------------------//
384
386{
387 return *m_group;
388}
389
390//----------------------------------------------------------------------------//
391
392void Partition::setGroup(boost::shared_ptr<OgOGroup> ptr)
393{
394 m_group = ptr;
395}
396
397//----------------------------------------------------------------------------//
398
399} // namespace File
400
401//----------------------------------------------------------------------------//
402// Field3DFileBase implementations
403//----------------------------------------------------------------------------//
404
406 : m_metadata(this)
407{
408 // Empty
409}
410
411//----------------------------------------------------------------------------//
412
418
419//----------------------------------------------------------------------------//
420
421std::string
422Field3DFileBase::intPartitionName(const std::string &partitionName,
423 const std::string & /* layerName */,
424 FieldRes::Ptr field)
425{
426 // Loop over existing partitions and see if there's a matching mapping
427 for (PartitionList::const_iterator i = m_partitions.begin();
428 i != m_partitions.end(); ++i) {
429 if (removeUniqueId((**i).name) == partitionName) {
430 if ((**i).mapping->isIdentical(field->mapping())) {
431 return (**i).name;
432 }
433 }
434 }
435
436 // If there was no previously matching name, then make a new one
437
438 int nextIdx = -1;
439 if (m_partitionCount.find(partitionName) != m_partitionCount.end()) {
440 nextIdx = ++m_partitionCount[partitionName];
441 } else {
442 nextIdx = 0;
443 m_partitionCount[partitionName] = 0;
444 }
445
446 return makeIntPartitionName(partitionName, nextIdx);
447}
448
449//----------------------------------------------------------------------------//
450
451File::Partition::Ptr Field3DFileBase::partition(const string &partitionName)
452{
453 for (PartitionList::iterator i = m_partitions.begin();
454 i != m_partitions.end(); ++i) {
455 if ((**i).name == partitionName)
456 return *i;
457 }
458
459 return File::Partition::Ptr();
460}
461
462//----------------------------------------------------------------------------//
463
465Field3DFileBase::partition(const string &partitionName) const
466{
467 for (PartitionList::const_iterator i = m_partitions.begin();
468 i != m_partitions.end(); ++i) {
469 if ((**i).name == partitionName)
470 return *i;
471 }
472
473 return File::Partition::Ptr();
474}
475
476//----------------------------------------------------------------------------//
477
478std::string
479Field3DFileBase::removeUniqueId(const std::string &partitionName) const
480{
481 size_t pos = partitionName.rfind(".");
482 if (pos == partitionName.npos) {
483 return partitionName;
484 } else {
485 return partitionName.substr(0, pos);
486 }
487}
488
489//----------------------------------------------------------------------------//
490
491void
493{
494 if (m_hdf5Base) {
495 m_hdf5Base->getPartitionNames(names);
496 return;
497 }
498
499 names.clear();
500
502
503 for (PartitionList::const_iterator i = m_partitions.begin();
504 i != m_partitions.end(); ++i) {
505 tempNames.push_back(removeUniqueId((**i).name));
506 }
507
509}
510
511//----------------------------------------------------------------------------//
512
513void
515 const string &partitionName) const
516{
517 if (m_hdf5Base) {
518 m_hdf5Base->getScalarLayerNames(names, partitionName);
519 return;
520 }
521
523
524 names.clear();
525
526 for (int i = 0; i < numIntPartitions(partitionName); i++) {
527 string internalName = makeIntPartitionName(partitionName, i);
529 if (part)
530 part->getLayerNames(names);
531 }
532
534}
535
536//----------------------------------------------------------------------------//
537
538void
540 const string &partitionName) const
541{
542 if (m_hdf5Base) {
543 m_hdf5Base->getVectorLayerNames(names, partitionName);
544 return;
545 }
546
548
549 names.clear();
550
551 for (int i = 0; i < numIntPartitions(partitionName); i++) {
552 string internalName = makeIntPartitionName(partitionName, i);
554 if (part)
555 part->getLayerNames(names);
556 }
557
559}
560
561//----------------------------------------------------------------------------//
562
563void
565{
566 names.clear();
567
568 for (PartitionList::const_iterator i = m_partitions.begin();
569 i != m_partitions.end(); ++i) {
570 names.push_back((**i).name);
571 }
572}
573
574//----------------------------------------------------------------------------//
575
576void
578 const string &intPartitionName) const
579{
581
582 names.clear();
583
585
586 if (!part) {
587 Msg::print("getIntScalarLayerNames no partition: " + intPartitionName);
588 return;
589 }
590
591 part->getLayerNames(names);
592}
593
594//----------------------------------------------------------------------------//
595
596void
598 const string &intPartitionName) const
599{
601
602 names.clear();
603
605
606 if (!part) {
607 Msg::print("getIntVectorLayerNames no partition: " + intPartitionName);
608 return;
609 }
610
611 part->getLayerNames(names);
612}
613
614//----------------------------------------------------------------------------//
615
617{
618 if (m_hdf5Base) {
619 m_hdf5Base->clear();
620 return;
621 }
622
624 m_partitions.clear();
625 m_groupMembership.clear();
626}
627
628//----------------------------------------------------------------------------//
629
631{
632 if (m_hdf5Base) {
633 return m_hdf5Base->close();
634 }
635
637
638 return true;
639}
640
641//----------------------------------------------------------------------------//
642
643int
644Field3DFileBase::numIntPartitions(const std::string &partitionName) const
645{
646 int count = 0;
647
648 for (PartitionList::const_iterator i = m_partitions.begin();
649 i != m_partitions.end(); ++i) {
650 string name = (**i).name;
651 size_t pos = name.rfind(".");
652 if (pos != name.npos) {
653 if (name.substr(0, pos) == partitionName) {
654 count++;
655 }
656 }
657 }
658
659 return count;
660}
661
662//----------------------------------------------------------------------------//
663
664string
665Field3DFileBase::makeIntPartitionName(const std::string &partitionName,
666 int i) const
667{
668 return partitionName + "." + boost::lexical_cast<std::string>(i);
669}
670
671//----------------------------------------------------------------------------//
672
673void
675{
676 if (m_hdf5Base) {
677 m_hdf5Base->addGroupMembership(groupMembers);
678 return;
679 }
680
681 GroupMembershipMap::const_iterator i = groupMembers.begin();
682 GroupMembershipMap::const_iterator end = groupMembers.end();
683
684 for (; i != end; ++i) {
685 GroupMembershipMap::iterator foundGroupIter =
686 m_groupMembership.find(i->first);
687 if (foundGroupIter != m_groupMembership.end()){
688 std::string value = m_groupMembership[i->first] + i->second;
689 m_groupMembership[i->first] = value;
690 } else {
691 m_groupMembership[i->first] = i->second;
692 }
693 }
694}
695
696//----------------------------------------------------------------------------//
697// Field3DInputFile implementations
698//----------------------------------------------------------------------------//
699
701{
702 // Empty
703}
704
705//----------------------------------------------------------------------------//
706
711
712//----------------------------------------------------------------------------//
713
714bool Field3DInputFile::open(const string &filename)
715{
716 clear();
717
718 bool success = true;
719
720 // Record filename
721 m_filename = filename;
722
723 try {
724
725 // Throws exceptions if the file doesn't exist.
726 checkFile(filename);
727
728 // Open the Ogawa archive
729 m_archive.reset(new Alembic::Ogawa::IArchive(filename));
730
731 // Error check and HDF5 fallback
732 if (!m_archive->isValid()) {
733 m_hdf5.reset(new Field3DInputFileHDF5);
735 if (m_hdf5->open(filename)) {
736 // Handled. Just return.
737 return true;
738 } else {
739 throw NoSuchFileException(filename);
740 }
741 }
742
743 // Grab the root group
744 m_root.reset(new OgIGroup(*m_archive));
745
746 // Check version number
747 try {
748 OgIAttribute<veci32_t> version =
749 m_root->findAttribute<veci32_t>(k_versionAttrName);
750 if (!version.isValid()) {
751 throw OgIAttributeException("Missing version attribute.");
752 }
753 int fileVersion[3] = { version.value()[0],
754 version.value()[1],
755 version.value()[2] };
758 versionStr << fileVersion[0] << "."
759 << fileVersion[1] << "."
760 << fileVersion[2];
762 }
763 }
764 catch (OgIAttributeException &e) {
765
766 }
767
768 // Read the global metadata. This does not always exists,
769 // depends on if it was written or not.
770 try {
771 const OgIGroup metadataGroup = m_root->findGroup("field3d_global_metadata");
772 if (metadataGroup.isValid()) {
774 }
775 }
776 catch (...) {
778 "Unknown error when reading file metadata ");
779 }
780
781 // Read the partition and layer info
782 try {
784 success = false;
785 }
786 }
787 catch (MissingGroupException &e) {
788 Msg::print(Msg::SevWarning, "Missing group: " + string(e.what()));
789 throw BadFileHierarchyException(filename);
790 }
791 catch (ReadMappingException &e) {
792 Msg::print(Msg::SevWarning, "Couldn't read mapping for partition: "
793 + string(e.what()));
794 throw BadFileHierarchyException(filename);
795 }
796 catch (Exception &e) {
797 Msg::print(Msg::SevWarning, "Unknown error when reading file hierarchy: "
798 + string(e.what()));
799 throw BadFileHierarchyException(filename);
800 }
801 catch (...) {
803 "Unknown error when reading file hierarchy. ");
804 throw BadFileHierarchyException(filename);
805 }
806 }
807 catch (NoSuchFileException &e) {
808 Msg::print(Msg::SevWarning, "Couldn't open file: "
809 + string(e.what()) );
810 success = false;
811 }
814 "In file: " + filename + " - "
815 + string(e.what()) );
816 success = false;
817 }
820 "In file: " + filename + " - File version can not be read: "
821 + string(e.what()));
822 success = false;
823 }
824 catch (BadFileHierarchyException &) {
826 "In file: " + filename + " - Bad file hierarchy. ");
827 success = false;
828 }
829 catch (runtime_error &e) {
830 // HDF5 fallback
831 m_hdf5.reset(new Field3DInputFileHDF5);
833 if (m_hdf5->open(filename)) {
834 // Handled. Just return.
835 return true;
836 } else {
838 "In file: " + filename + ": " + string(e.what()));
839 success = false;
840 }
841 }
842 catch (...) {
844 "In file: " + filename + " Unknown exception ");
845 success = false;
846 }
847
848 if (!success) {
849 close();
850 }
851
852 return success;
853}
854
855//----------------------------------------------------------------------------//
856
858{
859 // Find all the partition names
860 std::vector<std::string> groups = m_root->groupNames();
861
862 // Store the partition names
863 m_partitions.clear();
864 for (std::vector<std::string>::const_iterator i = groups.begin(),
865 end = groups.end(); i != end; ++i) {
866 // Grab the name
867 const std::string &name = *i;
868 // Skip metadata
869 if (name == "field3d_global_metadata") {
870 continue;
871 }
872 // Build partition
874 part->name = name;
875 m_partitions.push_back(part);
876 }
877
878 // For each partition, find its mapping ---
879
880 for (PartitionList::iterator i = m_partitions.begin();
881 i != m_partitions.end(); ++i) {
882 // Grab the name
883 const std::string &name = (**i).name;
884 // Open the partition group
885 const OgIGroup partitionGroup = m_root->findGroup(name);
886 if (!partitionGroup.isValid()) {
887 Msg::print(Msg::SevWarning, "Couldn't open partition group " + name);
888 }
889 // Open the mapping group
891 if (!mappingGroup.isValid()) {
892 Msg::print(Msg::SevWarning, "Couldn't open mapping group " + name);
893 }
894 // Build the mapping
896#if 0
897 if (!mapping) {
898 Msg::print(Msg::SevWarning, "Got a null pointer when reading mapping");
899 throw ReadMappingException((**i).name);
900 }
901#endif
902 // Attach the mapping to the partition
903 (**i).mapping = mapping;
904 }
905
906 // ... And then find its layers ---
907
908 for (PartitionList::const_iterator i = m_partitions.begin();
909 i != m_partitions.end(); ++i) {
910 // Grab the name
911 const std::string &partitionName = (**i).name;
912 // Open the partition group
913 const OgIGroup partitionGroup = m_root->findGroup(partitionName);
914 if (!partitionGroup.isValid()) {
915 Msg::print(Msg::SevWarning, "Couldn't open partition group " +
916 partitionName);
917 }
918 // Get all the layer names
919 groups = partitionGroup.groupNames();
920 for (std::vector<std::string>::const_iterator l = groups.begin(),
921 lEnd = groups.end(); l != lEnd; ++l) {
922 // Grab layer name
923 const std::string layerName = *l;
924 // Skip the mapping group
925 if (layerName == k_mappingStr) {
926 continue;
927 }
928 // Construct the layer
929 File::Layer layer;
930 layer.name = *l;
931 layer.parent = partitionName;
932 // Add to partition
933 partition(partitionName)->addLayer(layer);
934 }
935 }
936
937 return true;
938}
939
940//----------------------------------------------------------------------------//
941
943 FieldBase::Ptr field) const
944{
945 return readMeta(metadataGroup, field->metadata());
946}
947
948//----------------------------------------------------------------------------//
949
954
955//----------------------------------------------------------------------------//
956// Field3DOutputFile implementations
957//----------------------------------------------------------------------------//
958
960
961//----------------------------------------------------------------------------//
962
967
968//----------------------------------------------------------------------------//
969
974
975//----------------------------------------------------------------------------//
976
977bool Field3DOutputFile::create(const string &filename, CreateMode cm)
978{
979 if (!ms_doOgawa) {
980 m_hdf5.reset(new Field3DOutputFileHDF5);
982 int ccm = cm;
983 return m_hdf5->create(filename, Field3DOutputFileHDF5::CreateMode(ccm));
984 }
985
987
988 if (cm == FailOnExisting && fileExists(filename)) {
989 return false;
990 }
991
992 // Create the Ogawa archive
993 m_archive.reset(new Alembic::Ogawa::OArchive(filename));
994
995 // Check that it's valid
996 if (!m_archive->isValid()) {
997 m_archive.reset();
998 return false;
999 }
1000
1001 // Get the root
1002 m_root.reset(new OgOGroup(*m_archive));
1003
1004 // Create the version attribute
1007
1008 return true;
1009}
1010
1011//----------------------------------------------------------------------------//
1012
1014 FieldMapping::Ptr mapping)
1015{
1017 const std::string className = mapping->className();
1018
1019 try {
1020
1022
1024 className);
1025
1026 FieldMappingIO::Ptr io = factory.createFieldMappingIO(className);
1027 if (!io) {
1028 Msg::print(Msg::SevWarning, "Unable to find class type: " +
1029 className);
1030 return false;
1031 }
1032
1033 return io->write(mappingGroup, mapping);
1034
1035 }
1036 catch (OgOGroupException &e) {
1037 Msg::print(Msg::SevWarning, "Couldn't create group: " + string(e.what()) );
1039 }
1040
1041}
1042
1043//----------------------------------------------------------------------------//
1044
1046 FieldBase::Ptr field)
1047{
1048 {
1049 FieldMetadata::StrMetadata::const_iterator i =
1050 field->metadata().strMetadata().begin();
1051 FieldMetadata::StrMetadata::const_iterator end =
1052 field->metadata().strMetadata().end();
1053 for (; i != end; ++i) {
1054 try {
1055 OgOAttribute<string>(metadataGroup, i->first, i->second);
1056 }
1057 catch (OgOAttributeException &e) {
1058 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1059 " " + e.what());
1060 return false;
1061 }
1062 }
1063 }
1064
1065 {
1066 FieldMetadata::IntMetadata::const_iterator i =
1067 field->metadata().intMetadata().begin();
1068 FieldMetadata::IntMetadata::const_iterator end =
1069 field->metadata().intMetadata().end();
1070 for (; i != end; ++i) {
1071 try {
1072 OgOAttribute<int32_t>(metadataGroup, i->first, i->second);
1073 }
1074 catch (OgOAttributeException &e) {
1075 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1076 " " + e.what());
1077 return false;
1078 }
1079 }
1080 }
1081
1082 {
1083 FieldMetadata::FloatMetadata::const_iterator i =
1084 field->metadata().floatMetadata().begin();
1085 FieldMetadata::FloatMetadata::const_iterator end =
1086 field->metadata().floatMetadata().end();
1087 for (; i != end; ++i) {
1088 try {
1089 OgOAttribute<float32_t>(metadataGroup, i->first, i->second);
1090 }
1091 catch (OgOAttributeException &e) {
1092 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1093 " " + e.what());
1094 return false;
1095 }
1096 }
1097 }
1098
1099 {
1100 FieldMetadata::VecIntMetadata::const_iterator i =
1101 field->metadata().vecIntMetadata().begin();
1102 FieldMetadata::VecIntMetadata::const_iterator end =
1103 field->metadata().vecIntMetadata().end();
1104 for (; i != end; ++i) {
1105 try {
1106 OgOAttribute<veci32_t>(metadataGroup, i->first, i->second);
1107 }
1108 catch (OgOAttributeException &e) {
1109 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1110 " " + e.what());
1111 return false;
1112 }
1113 }
1114 }
1115
1116 {
1117 FieldMetadata::VecFloatMetadata::const_iterator i =
1118 field->metadata().vecFloatMetadata().begin();
1119 FieldMetadata::VecFloatMetadata::const_iterator end =
1120 field->metadata().vecFloatMetadata().end();
1121 for (; i != end; ++i) {
1122 try {
1123 OgOAttribute<vec32_t>(metadataGroup, i->first, i->second);
1124 }
1125 catch (OgOAttributeException &e) {
1126 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1127 " " + e.what());
1128 return false;
1129 }
1130 }
1131
1132 }
1133
1134 return true;
1135
1136}
1137
1138//----------------------------------------------------------------------------//
1139
1141{
1142 {
1143 FieldMetadata::StrMetadata::const_iterator i =
1144 metadata().strMetadata().begin();
1145 FieldMetadata::StrMetadata::const_iterator end =
1146 metadata().strMetadata().end();
1147 for (; i != end; ++i) {
1148 try {
1149 OgOAttribute<string>(metadataGroup, i->first, i->second);
1150 }
1151 catch (OgOAttributeException &e) {
1152 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1153 " " + e.what());
1154 return false;
1155 }
1156 }
1157 }
1158
1159 {
1160 FieldMetadata::IntMetadata::const_iterator i =
1161 metadata().intMetadata().begin();
1162 FieldMetadata::IntMetadata::const_iterator end =
1163 metadata().intMetadata().end();
1164 for (; i != end; ++i) {
1165 try {
1166 OgOAttribute<int32_t>(metadataGroup, i->first, i->second);
1167 }
1168 catch (OgOAttributeException &e) {
1169 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1170 " " + e.what());
1171 return false;
1172 }
1173 }
1174 }
1175
1176 {
1177 FieldMetadata::FloatMetadata::const_iterator i =
1178 metadata().floatMetadata().begin();
1179 FieldMetadata::FloatMetadata::const_iterator end =
1180 metadata().floatMetadata().end();
1181 for (; i != end; ++i) {
1182 try {
1183 OgOAttribute<float32_t>(metadataGroup, i->first, i->second);
1184 }
1185 catch (OgOAttributeException &e) {
1186 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1187 " " + e.what());
1188 return false;
1189 }
1190 }
1191 }
1192
1193 {
1194 FieldMetadata::VecIntMetadata::const_iterator i =
1195 metadata().vecIntMetadata().begin();
1196 FieldMetadata::VecIntMetadata::const_iterator end =
1197 metadata().vecIntMetadata().end();
1198 for (; i != end; ++i) {
1199 try {
1200 OgOAttribute<veci32_t>(metadataGroup, i->first, i->second);
1201 }
1202 catch (OgOAttributeException &e) {
1203 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1204 " " + e.what());
1205 return false;
1206 }
1207 }
1208 }
1209
1210 {
1211 FieldMetadata::VecFloatMetadata::const_iterator i =
1212 metadata().vecFloatMetadata().begin();
1213 FieldMetadata::VecFloatMetadata::const_iterator end =
1214 metadata().vecFloatMetadata().end();
1215 for (; i != end; ++i) {
1216 try {
1217 OgOAttribute<vec32_t>(metadataGroup, i->first, i->second);
1218 }
1219 catch (OgOAttributeException &e) {
1220 Msg::print(Msg::SevWarning, "Writing attribute " + i->first +
1221 " " + e.what());
1222 return false;
1223 }
1224 }
1225
1226 }
1227
1228 return true;
1229}
1230
1231//----------------------------------------------------------------------------//
1232
1233bool
1235{
1236 if (m_hdf5) {
1237 return m_hdf5->writeGlobalMetadata();
1238 }
1239
1240 OgOGroup ogMetadata(*m_root, "field3d_global_metadata");
1241 if (!writeMetadata(ogMetadata)) {
1242 Msg::print(Msg::SevWarning, "Error writing file metadata.");
1243 return false;
1244 }
1245
1246 return true;
1247}
1248
1249//----------------------------------------------------------------------------//
1250
1251bool
1253{
1254 if (m_hdf5) {
1255 return m_hdf5->writeGroupMembership();
1256 }
1257
1258#if 0
1259
1261
1262 using namespace std;
1263 using namespace Hdf5Util;
1264
1265 if (!m_groupMembership.size())
1266 return true;
1267
1268 H5ScopedGcreate group(m_file, "field3d_group_membership");
1269 if (group < 0) {
1271 "Error creating field3d_group_membership group.");
1272 return false;
1273 }
1274
1275 if (!writeAttribute(group, "is_field3d_group_membership", "1")) {
1277 "Failed to write field3d_group_membership attribute.");
1278 return false;
1279 }
1280
1281 std::map<std::string, std::string>::const_iterator iter =
1282 m_groupMembership.begin();
1283 std::map<std::string, std::string>::const_iterator iEnd =
1284 m_groupMembership.end();
1285
1286 for (; iter != iEnd; ++iter) {
1287 if (!writeAttribute(group, iter->first, iter->second)) {
1289 "Failed to write groupMembership string: "+ iter->first);
1290 return false;
1291 }
1292 }
1293
1294#endif
1295
1296 return true;
1297}
1298
1299//----------------------------------------------------------------------------//
1300
1301std::string
1303{
1304 std::string myPartitionName = removeUniqueId(partitionName);
1305 int nextIdx = -1;
1308 } else {
1309 nextIdx = 0;
1311 }
1312
1314}
1315
1316//----------------------------------------------------------------------------//
1317// Debug
1318//----------------------------------------------------------------------------//
1319
1321{
1322 // For each partition
1323 for (PartitionList::const_iterator i = m_partitions.begin();
1324 i != m_partitions.end(); ++i) {
1325 cout << "Name: " << (**i).name << endl;
1326 if ((**i).mapping)
1327 cout << " Mapping: " << (**i).mapping->className() << endl;
1328 else
1329 cout << " Mapping: NULL" << endl;
1330 cout << " Layers: " << endl;
1332 (**i).getLayerNames(names);
1333 for_each(names.begin(), names.end(), print<string>(4));
1334 }
1335}
1336
1337//----------------------------------------------------------------------------//
1338// Function Implementations
1339//----------------------------------------------------------------------------//
1340
1341bool fileExists(const std::string &filename)
1342{
1343#ifdef WIN32
1344 struct __stat64 statbuf;
1345 return (_stat64(filename.c_str(), &statbuf) != -1);
1346#else
1347 struct stat statbuf;
1348 return (stat(filename.c_str(), &statbuf) != -1);
1349#endif
1350}
1351
1352//----------------------------------------------------------------------------//
1353
1355Field3DOutputFile::createNewPartition(const std::string &partitionName,
1356 const std::string & /* layerName */,
1357 FieldRes::Ptr field)
1358{
1359 using namespace Exc;
1360
1362 newPart->name = partitionName;
1363
1364 boost::shared_ptr<OgOGroup> ogPartition(new OgOGroup(*m_root, newPart->name));
1365 newPart->setGroup(ogPartition);
1366
1367 m_partitions.push_back(newPart);
1368
1369 // Pick up new pointer
1370 File::Partition::Ptr part = partition(partitionName);
1371
1372 // Add mapping group to the partition
1373 try {
1374 if (!writeMapping(*ogPartition, field->mapping())) {
1376 "writeMapping returned false for an unknown reason ");
1377 return File::Partition::Ptr();
1378 }
1379 }
1380 catch (WriteMappingException &e) {
1381 Msg::print(Msg::SevWarning, "Couldn't write mapping for partition: "
1382 + partitionName);
1383 return File::Partition::Ptr();
1384 }
1385 catch (...) {
1387 "Unknown error when writing mapping for partition: "
1388 + partitionName);
1389 return File::Partition::Ptr();
1390 }
1391
1392 // Set the mapping of the partition. Since all layers share their
1393 // partition's mapping, we can just pick this first one. All subsequent
1394 // additions to the same partition are checked to have the same mapping
1395 part->mapping = field->mapping();
1396
1397 // Tag node as partition
1398 // Create a version attribute on the root node
1399 OgOAttribute<string>(*ogPartition, "is_field3d_partition", "1");
1400
1401 return part;
1402}
1403
1404//----------------------------------------------------------------------------//
1405// Template implementations
1406//----------------------------------------------------------------------------//
1407
1408template <class Data_T>
1410 const std::string &layerName,
1411 typename Field<Data_T>::Ptr field)
1412{
1413 using std::string;
1414
1415 // Null pointer check
1416 if (!field) {
1418 "Called writeLayer with null pointer. Ignoring...");
1419 return false;
1420 }
1421
1422 // Make sure archive is open
1423 if (!m_archive) {
1425 "Attempting to write layer without opening file first.");
1426 return false;
1427 }
1428
1429 // Get the partition name
1430 string partitionName = intPartitionName(userPartitionName, layerName, field);
1431
1432 // Get the partition
1433 File::Partition::Ptr part = partition(partitionName);
1434
1435 if (!part) {
1436 // Create a new partition
1437 part = createNewPartition(partitionName, layerName, field);
1438 // Make sure it was created
1439 if (!part) {
1440 return false;
1441 }
1442 } else {
1443 // Check that we have a valid mapping
1444 if (!field->mapping()) {
1446 "Couldn't add layer \"" + layerName + "\" to partition \""
1447 + partitionName + "\" because the layer's mapping is null.");
1448 return false;
1449 }
1450 // Check if the layer already exists. If it does, we need to make a
1451 // different partition
1452 if (part->layer(layerName)) {
1453 // Increment the internal partition name
1454 partitionName = incrementPartitionName(partitionName);
1455 // Create a new partition
1456 part = createNewPartition(partitionName, layerName, field);
1457 // Make sure it was created
1458 if (!part) {
1459 return false;
1460 }
1461 }
1462 }
1463
1464 // Check mapping not null
1465 if (!part->mapping) {
1466 Msg::print(Msg::SevWarning, "Severe error - partition mapping is null: "
1467 + partitionName);
1468 return false;
1469 }
1470
1471 // Check that the mapping matches what's already in the Partition
1472 if (!field->mapping()->isIdentical(part->mapping)) {
1473 Msg::print(Msg::SevWarning, "Couldn't add layer \"" + layerName
1474 + "\" to partition \"" + partitionName
1475 + "\" because mapping doesn't match");
1476 return false;
1477 }
1478
1479 // Open the partition
1480
1481 OgOGroup &ogPartition = part->group();
1482
1483 // Build a Layer
1484
1485 File::Layer layer;
1486 layer.name = layerName;
1487 layer.parent = partitionName;
1488
1489 // Add Layer to file ---
1490
1492
1493 // Tag as layer
1494 OgOAttribute<string> classType(ogLayer, "class_type", "field3d_layer");
1495
1496 // Create metadata
1497 OgOGroup ogMetadata(ogLayer, "metadata");
1498
1499 // Write metadata
1500 writeMetadata(ogMetadata, field);
1501
1502 // Write field data
1503 writeField(ogLayer, field);
1504
1505 // Add to partition
1506
1507 part->addLayer(layer);
1508
1509 return true;
1510}
1511
1512//----------------------------------------------------------------------------//
1513
1514template <class Data_T>
1515typename Field<Data_T>::Ptr
1516Field3DInputFile::readLayer(const std::string &intPartitionName,
1517 const std::string &layerName) const
1518{
1519 typedef typename Field<Data_T>::Ptr FieldPtr;
1520
1521 // Instantiate a null pointer for easier code reading
1522 FieldPtr nullPtr;
1523
1524 // Find the partition
1526 if (!part) {
1527 Msg::print(Msg::SevWarning, "Couldn't find partition: " + intPartitionName);
1528 return nullPtr;
1529 }
1530
1531 // Find the layer
1532 const File::Layer *layer = part->layer(layerName);
1533 if (!layer) {
1534 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName);
1535 return nullPtr;
1536 }
1537
1538 // Open the partition group
1539 const OgIGroup partitionGroup = m_root->findGroup(intPartitionName);
1540 if (!partitionGroup.isValid()) {
1541 Msg::print(Msg::SevWarning, "Couldn't open partition group " +
1543 return nullPtr;
1544 }
1545
1546 // Open the layer group
1547 const OgIGroup layerGroup = partitionGroup.findGroup(layerName);
1548 if (!layerGroup.isValid()) {
1549 Msg::print(Msg::SevWarning, "Couldn't open layer group " +
1550 layerName);
1551 return nullPtr;
1552 }
1553
1554 // Get the class name
1555 string layerPath = layer->parent + "/" + layer->name;
1556 string className;
1557 try {
1558 className = layerGroup.findAttribute<string>("class_name").value();
1559 }
1560 catch (OgIAttributeException &e) {
1561 Msg::print(Msg::SevWarning, "Couldn't find class_name attrib in layer " +
1562 layerName);
1563 return nullPtr;
1564 }
1565
1566 // Check the cache
1567
1569 FieldPtr cachedField = cache.getCachedField(m_filename, layerPath);
1570
1571 if (cachedField) {
1572 return cachedField;
1573 }
1574
1575 // Construct the field and load the data
1576
1577 typename Field<Data_T>::Ptr field;
1578 field = readField<Data_T>(className, layerGroup, m_filename, layerPath);
1579
1580 if (!field) {
1581 // This isn't really an error
1582 return nullPtr;
1583 }
1584
1585 // Read the metadata
1586 const OgIGroup metadataGroup = layerGroup.findGroup("metadata");
1587 if (metadataGroup.isValid()) {
1589 }
1590
1591 // Set the name of the field appropriately
1593 field->attribute = layerName;
1594 field->setMapping(part->mapping);
1595
1596 // Cache the field for future use
1597 if (field) {
1598 cache.cacheField(field, m_filename, layerPath);
1599 }
1600
1601 return field;
1602}
1603
1604//----------------------------------------------------------------------------//
1605
1606template <class Data_T>
1607typename Field<Data_T>::Vec
1608Field3DInputFile::readLayers(const std::string &name) const
1609{
1610 using std::vector;
1611 using std::string;
1612
1613 typedef typename Field<Data_T>::Ptr FieldPtr;
1614 typedef typename Field<Data_T>::Vec FieldList;
1615
1616 FieldList ret;
1617 std::vector<std::string> parts;
1619
1620 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
1623 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
1624 // Only read if it matches the name
1625 if ((name.length() == 0) || (*l == name)) {
1626 FieldPtr mf = readLayer<Data_T>(*p, *l);
1627 if (mf) {
1628 ret.push_back(mf);
1629 }
1630 }
1631 }
1632 }
1633
1634 return ret;
1635}
1636
1637//----------------------------------------------------------------------------//
1638
1639template <class Data_T>
1640typename Field<Data_T>::Vec
1641Field3DInputFile::readLayers(const std::string &partitionName,
1642 const std::string &layerName) const
1643{
1644 using namespace std;
1645
1646 typedef typename Field<Data_T>::Ptr FieldPtr;
1647 typedef typename Field<Data_T>::Vec FieldList;
1648
1649 FieldList ret;
1650
1651 if ((layerName.length() == 0) || (partitionName.length() == 0))
1652 return ret;
1653
1654 std::vector<std::string> parts;
1656
1657 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
1658 std::vector<std::string> layers;
1660 if (removeUniqueId(*p) == partitionName) {
1661 for (vector<string>::iterator l = layers.begin();
1662 l != layers.end(); ++l) {
1663 // Only read if it matches the name
1664 if (*l == layerName) {
1665 FieldPtr mf = readLayer<Data_T>(*p, *l);
1666 if (mf)
1667 ret.push_back(mf);
1668 }
1669 }
1670 }
1671 }
1672
1673 return ret;
1674}
1675
1676//----------------------------------------------------------------------------//
1677
1678template <class Data_T>
1681 const std::string &name,
1682 const std::string &attribute,
1683 FieldMapping::Ptr mapping) const
1684{
1685 using namespace boost;
1686 using namespace std;
1687
1689
1690 const std::string extentsMinStr("extents_min");
1691 const std::string extentsMaxStr("extents_max");
1692 const std::string dataWindowMinStr("data_window_min");
1693 const std::string dataWindowMaxStr("data_window_max");
1694
1695 Box3i extents, dataW;
1696
1697 // Get extents ---
1698
1700 location.findAttribute<veci32_t>(extentsMinStr);
1702 location.findAttribute<veci32_t>(extentsMaxStr);
1703 if (!extMinAttr.isValid()) {
1704 throw MissingAttributeException("Couldn't find attribute " +
1706 }
1707 if (!extMaxAttr.isValid()) {
1708 throw MissingAttributeException("Couldn't find attribute " +
1710 }
1711
1712 extents.min = extMinAttr.value();
1713 extents.max = extMaxAttr.value();
1714
1715 // Get data window ---
1716
1718 location.findAttribute<veci32_t>(dataWindowMinStr);
1720 location.findAttribute<veci32_t>(dataWindowMaxStr);
1721 if (!dwMinAttr.isValid()) {
1722 throw MissingAttributeException("Couldn't find attribute " +
1724 }
1725 if (!dwMaxAttr.isValid()) {
1726 throw MissingAttributeException("Couldn't find attribute " +
1728 }
1729
1730 dataW.min = dwMinAttr.value();
1731 dataW.max = dwMaxAttr.value();
1732
1733 // Construct the field
1734 typename EmptyField<Data_T>::Ptr field(new EmptyField<Data_T>);
1735 field->setSize(extents, dataW);
1736
1737 // Read the metadata
1738 OgIGroup metadataGroup = location.findGroup("metadata");
1739 if (metadataGroup.isValid()) {
1741 }
1742
1743 // Set field properties
1744 field->name = name;
1745 field->attribute = attribute;
1746 field->setMapping(mapping);
1747
1748 return field;
1749}
1750
1751//----------------------------------------------------------------------------//
1752
1753template <class Data_T>
1755Field3DInputFile::readProxyLayer(const std::string &partitionName,
1756 const std::string &layerName,
1757 bool isVectorLayer) const
1758{
1759 using namespace boost;
1760 using namespace std;
1761 using namespace Hdf5Util;
1762
1763 if (m_hdf5) {
1764 return m_hdf5->readProxyLayer<Data_T>(partitionName, layerName,
1766 }
1767
1768 // Instantiate a null pointer for easier code reading
1770
1771 if ((layerName.length() == 0) || (partitionName.length() == 0))
1772 return emptyList;
1773
1774 std::vector<std::string> parts, layers;
1776
1777 bool foundPartition = false;
1778
1779 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
1780 if (removeUniqueId(*p) == partitionName) {
1781 foundPartition = true;
1782 if (isVectorLayer) {
1784 } else {
1786 }
1787 for (vector<string>::iterator l = layers.begin();
1788 l != layers.end(); ++l) {
1789 if (*l == layerName) {
1790 // Find the partition
1792 if (!part) {
1793 Msg::print(Msg::SevWarning, "Couldn't find partition: " + *p);
1794 return emptyList;
1795 }
1796 // Find the layer
1797 const File::Layer *layer;
1798 if (isVectorLayer) {
1799 layer = part->layer(layerName);
1800 } else {
1801 layer = part->layer(layerName);
1802 }
1803 if (!layer) {
1804 Msg::print(Msg::SevWarning, "Couldn't find layer: " + layerName);
1805 return emptyList;
1806 }
1807 // Open the layer group
1808 string layerPath = layer->parent + "/" + layer->name;
1809 OgIGroup parent = m_root->findGroup(layer->parent);
1810 if (!parent.isValid()) {
1811 Msg::print(Msg::SevWarning, "Couldn't find layer parent "
1812 + layerPath + " in .f3d file ");
1813 return emptyList;
1814 }
1815 OgIGroup layerGroup = parent.findGroup(layer->name);
1816 if (!layerGroup.isValid()) {
1817 Msg::print(Msg::SevWarning, "Couldn't find layer group "
1818 + layerPath + " in .f3d file ");
1819 return emptyList;
1820 }
1821
1822 // Make the proxy representation
1823 typename EmptyField<Data_T>::Ptr field =
1825 part->mapping);
1826
1827 // Read MIPField's number of mip levels
1828 int numLevels = 0;
1829 OgIGroup mipGroup = layerGroup.findGroup("mip_levels");
1830 if (mipGroup.isValid()) {
1832 mipGroup.findAttribute<uint32_t>("levels");
1833 if (levelsAttr.isValid()) {
1834 numLevels = levelsAttr.value();
1835 }
1836 }
1837 field->metadata().setIntMetadata("mip_levels", numLevels);
1838
1839 // Add field to output
1840 output.push_back(field);
1841 }
1842 }
1843 }
1844 }
1845
1846 if (!foundPartition) {
1847 Msg::print(Msg::SevWarning, "Couldn't find partition: " + partitionName);
1848 return emptyList;
1849 }
1850
1851 return output;
1852}
1853
1854//----------------------------------------------------------------------------//
1855
1856template <class Data_T>
1858Field3DInputFile::readProxyScalarLayers(const std::string &name) const
1859{
1860 using namespace std;
1861
1862 typedef typename EmptyField<Data_T>::Ptr FieldPtr;
1863 typedef std::vector<FieldPtr> FieldList;
1864
1865 FieldList ret;
1866
1867 std::vector<std::string> parts;
1869
1870 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
1871 std::vector<std::string> layers;
1873 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
1874 // Only read if it matches the name
1875 if ((name.length() == 0) || (*l == name)) {
1876 FieldList f = readProxyLayer<Data_T>(*p, *l, false);
1877 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) {
1878 if (*i) {
1879 ret.push_back(*i);
1880 }
1881 }
1882 }
1883 }
1884 }
1885
1886 return ret;
1887}
1888
1889//----------------------------------------------------------------------------//
1890
1891template <class Data_T>
1893Field3DInputFile::readProxyVectorLayers(const std::string &name) const
1894{
1895 using namespace std;
1896
1897 typedef typename EmptyField<Data_T>::Ptr FieldPtr;
1898 typedef std::vector<FieldPtr> FieldList;
1899
1900 FieldList ret;
1901
1902 std::vector<std::string> parts;
1904
1905 for (vector<string>::iterator p = parts.begin(); p != parts.end(); ++p) {
1906 std::vector<std::string> layers;
1908 for (vector<string>::iterator l = layers.begin(); l != layers.end(); ++l) {
1909 // Only read if it matches the name
1910 if ((name.length() == 0) || (*l == name)) {
1911 FieldList f = readProxyLayer<Data_T>(*p, *l, true);
1912 for (typename FieldList::iterator i = f.begin(); i != f.end(); ++i) {
1913 if (*i) {
1914 ret.push_back(*i);
1915 }
1916 }
1917 }
1918 }
1919 }
1920
1921 return ret;
1922}
1923
1924//----------------------------------------------------------------------------//
1925// Template instantiations
1926//----------------------------------------------------------------------------//
1927
1928#define FIELD3D_INSTANTIATION_WRITELAYER(type) \
1929 template \
1930 bool Field3DOutputFile::writeLayer<type> \
1931 (const std::string &, const std::string &, Field<type>::Ptr ); \
1932
1939
1940//----------------------------------------------------------------------------//
1941
1942#if 0
1943
1944#define FIELD3D_INSTANTIATION_READLAYER(type) \
1945 template \
1946 Field<type>::Ptr \
1947 Field3DInputFile::readLayer<type> \
1948 (const std::string &, const std::string &) const; \
1949
1956
1957#endif
1958
1959//----------------------------------------------------------------------------//
1960
1961#define FIELD3D_INSTANTIATION_READLAYERS1(type) \
1962 template \
1963 Field<type>::Vec \
1964 Field3DInputFile::readLayers<type>(const std::string &name) const; \
1965
1972
1973//----------------------------------------------------------------------------//
1974
1975#define FIELD3D_INSTANTIATION_READLAYERS2(type) \
1976 template \
1977 Field<type>::Vec \
1978 Field3DInputFile::readLayers<type>(const std::string &partitionName, \
1979 const std::string &layerName) const; \
1980
1987
1988//----------------------------------------------------------------------------//
1989
1990#define FIELD3D_INSTANTIATION_READPROXYLAYER(type) \
1991 template \
1992 EmptyField<type>::Vec \
1993 Field3DInputFile::readProxyLayer<type>(const std::string &partitionName, \
1994 const std::string &layerName, \
1995 bool isVectorLayer) const \
1996
2003
2004//----------------------------------------------------------------------------//
2005
2006#define FIELD3D_INSTANTIATION_READPROXYSCALARLAYER(type) \
2007 template \
2008 EmptyField<type>::Vec \
2009 Field3DInputFile::readProxyScalarLayers<type> \
2010 (const std::string &name) const \
2011
2018
2019//----------------------------------------------------------------------------//
2020
2021#define FIELD3D_INSTANTIATION_READPROXYVECTORLAYER(type) \
2022 template \
2023 EmptyField<type>::Vec \
2024 Field3DInputFile::readProxyVectorLayers<type> \
2025 (const std::string &name) const \
2026
2033
2034//----------------------------------------------------------------------------//
2035
2037
2038//----------------------------------------------------------------------------//
Contains the ClassFactory class for registering Field3D classes.
Contains the Field3DFileHDF5 classes.
Field< Data_T >::Ptr readField(const std::string &className, hid_t layerGroup, const std::string &filename, const std::string &layerPath)
This function creates a FieldIO instance based on className which then reads the field data from laye...
FIELD3D_API bool writeField(hid_t layerGroup, FieldBase::Ptr field)
This function creates a FieldIO instance based on field->className() which then writes the field data...
FIELD3D_API FieldMapping::Ptr readFieldMapping(hid_t mappingGroup)
This function creates a FieldMappingIO instance based on className read from mappingGroup location wh...
#define FIELD3D_INSTANTIATION_READPROXYLAYER(type)
#define FIELD3D_INSTANTIATION_WRITELAYER(type)
#define FIELD3D_INSTANTIATION_READPROXYVECTORLAYER(type)
#define FIELD3D_INSTANTIATION_READLAYERS1(type)
#define FIELD3D_INSTANTIATION_READLAYERS2(type)
#define FIELD3D_INSTANTIATION_READPROXYSCALARLAYER(type)
bool fileExists(const std::string &filename)
checks to see if a file/directory exists or not
Contains the Field3DFile classes.
bool fileExists(const std::string &filename)
checks to see if a file/directory exists or not
Contains the FieldCache class.
Contains Field, WritableField and ResizableField classes.
Imath::V3i V3i
Definition SpiMathLib.h:71
Imath::Box3i Box3i
Definition SpiMathLib.h:77
#define FIELD3D_MTX_T
Definition StdMathLib.h:99
Field3D::V3f vec32_t
Definition Traits.h:92
Field3D::V3i veci32_t
Definition Traits.h:94
float float32_t
Definition Traits.h:87
Field3D::V3h vec16_t
Definition Traits.h:91
Field3D::V3d vec64_t
Definition Traits.h:93
OgDataType
Enumerates the various uses for Ogawa-level groups.
Definition Traits.h:125
double float64_t
Definition Traits.h:88
half float16_t
Definition Traits.h:86
static ClassFactory & singleton()
}
This subclass of Field does not store any data.
Definition EmptyField.h:88
boost::intrusive_ptr< EmptyField > Ptr
Definition EmptyField.h:93
std::vector< Ptr > Vec
Definition EmptyField.h:94
boost::shared_ptr< Field3DFileHDF5Base > m_hdf5Base
HDF5 fallback.
GroupMembershipMap m_groupMembership
Keeps track of group membership for each layer of partition name. The key is the "group" and the valu...
std::string removeUniqueId(const std::string &partitionName) const
Strips any unique identifiers from the partition name and returns the original name.
void getIntPartitionNames(std::vector< std::string > &names) const
Gets the names of all the -internal- partitions in the file.
void getScalarLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the scalar layers in a given partition.
virtual ~Field3DFileBase()=0
Pure virtual destructor to ensure we never instantiate this class.
std::string makeIntPartitionName(const std::string &partitionsName, int i) const
Makes an internal partition name given the external partition name. Effectively just tacks on ....
FieldMetadata & metadata()
accessor to the m_metadata class
virtual void closeInternal()=0
Closes the file if open.
void getIntScalarLayerNames(std::vector< std::string > &names, const std::string &intPartitionName) const
Gets the names of all the scalar layers in a given partition, but assumes that partition name is the ...
void clear()
Clear the data structures and close the file.
PartitionList m_partitions
Vector of partitions.
File::Partition::Ptr partition(const std::string &partitionName)
Returns a pointer to the given partition.
void getPartitionNames(std::vector< std::string > &names) const
Gets the names of all the partitions in the file.
void getVectorLayerNames(std::vector< std::string > &names, const std::string &partitionName) const
Gets the names of all the vector layers in a given partition.
int numIntPartitions(const std::string &partitionName) const
Returns the number of internal partitions for a given partition name.
std::string intPartitionName(const std::string &partitionName, const std::string &layerName, FieldRes::Ptr field)
Returns a unique partition name given the requested name. This ensures that partitions with matching ...
void printHierarchy() const
PartitionCountMap m_partitionCount
Contains a counter for each partition name. This is used to keep multiple fields with the same name u...
std::map< std::string, std::string > GroupMembershipMap
void addGroupMembership(const GroupMembershipMap &groupMembers)
Add to the group membership.
void getIntVectorLayerNames(std::vector< std::string > &names, const std::string &intPartitionName) const
Gets the names of all the vector layers in a given partition, but assumes that partition name is the ...
bool close()
Closes the file. No need to call this unless you specifically want to close the file early....
Provides reading of .f3d (internally, hdf5) files.
EmptyField< Data_T >::Vec readProxyVectorLayers(const std::string &name=std::string("")) const
Retrieves a proxy version (EmptyField) of each vector layer.
std::string m_filename
Filename, only to be set by open().
EmptyField< Data_T >::Vec readProxyScalarLayers(const std::string &name=std::string("")) const
Retrieves a proxy version (EmptyField) of each scalar layer.
EmptyField< Data_T >::Vec readProxyLayer(const std::string &partitionName, const std::string &layerName, bool isVectorLayer) const
Retrieves a proxy version (EmptyField) of each layer .
Field< Data_T >::Vec readLayers(const std::string &layerName=std::string("")) const
boost::shared_ptr< OgIGroup > m_root
Pointer to root group.
boost::shared_ptr< Field3DInputFileHDF5 > m_hdf5
HDF5 fallback.
Field< Data_T >::Ptr readLayer(const std::string &intPartitionName, const std::string &layerName) const
This call does the actual reading of a layer. Notice that it expects a unique -internal- partition na...
boost::shared_ptr< Alembic::Ogawa::IArchive > m_archive
Pointer to the Ogawa archive.
bool readPartitionAndLayerInfo()
Sets up all the partitions and layers, but does not load any data.
bool readMetadata(const OgIGroup &metadataGroup, FieldBase::Ptr field) const
Read metadata for this layer.
bool open(const std::string &filename)
Opens the given file.
virtual ~Field3DInputFile()
Provides writing of .f3d (internally, hdf5) files.
static bool ms_doOgawa
Whether to output ogawa files.
virtual void closeInternal()
Closes the file if open.
boost::shared_ptr< Field3DOutputFileHDF5 > m_hdf5
HDF5 fallback.
bool writeLayer(const std::string &layerName, typename Field< Data_T >::Ptr layer)
Writes a scalar layer to the "Default" partition.
File::Partition::Ptr createNewPartition(const std::string &partitionName, const std::string &layerName, FieldRes::Ptr field)
Create newPartition given the input config.
virtual ~Field3DOutputFile()
bool create(const std::string &filename, CreateMode cm=OverwriteMode)
Creates a .f3d file on disk.
bool writeGlobalMetadata()
This routine is call if you want to write out global metadata to disk.
boost::shared_ptr< OgOGroup > m_root
Pointer to root group.
boost::shared_ptr< Alembic::Ogawa::OArchive > m_archive
Pointer to the Ogawa archive.
bool writeMapping(OgOGroup &partitionGroup, FieldMapping::Ptr mapping)
Writes the mapping to the given Og node. Mappings are assumed to be light-weight enough to be stored ...
bool writeGroupMembership()
This routine is called just before closing to write out any group membership to disk.
bool writeMetadata(OgOGroup &metadataGroup, FieldBase::Ptr layer)
Writes metadata for this layer.
std::string incrementPartitionName(std::string &pname)
Increment the partition or make it zero if there's not an integer suffix.
boost::intrusive_ptr< FieldBase > Ptr
Definition Field.h:97
FieldMetadata & metadata()
accessor to the m_metadata class
Definition Field.h:155
std::string attribute
Optional name of the attribute the field represents.
Definition Field.h:173
std::string name
Optional name of the field.
Definition Field.h:171
static FieldCache & singleton()
Returns a reference to the FieldCache singleton.
Definition FieldCache.h:135
boost::intrusive_ptr< FieldIO > Ptr
Definition FieldIO.h:91
boost::intrusive_ptr< FieldMappingIO > Ptr
boost::intrusive_ptr< FieldMapping > Ptr
void setIntMetadata(const std::string &name, const int val)
Set the a int value for the given metadata name.
void setStrMetadata(const std::string &name, const std::string &val)
Set the a string value for the given metadata name.
void setVecFloatMetadata(const std::string &name, const V3f &val)
Set the a V3f value for the given metadata name.
void setVecIntMetadata(const std::string &name, const V3i &val)
Set the a V3i value for the given metadata name.
V3f vecFloatMetadata(const std::string &name, const V3f &defaultVal) const
Tries to retrieve a V3f metadata value. Returns the specified default value if no metadata was found.
V3i vecIntMetadata(const std::string &name, const V3i &defaultVal) const
Tries to retrieve a V3i metadata value. Returns the specified default value if no metadata was found.
int intMetadata(const std::string &name, const int defaultVal) const
Tries to retrieve an int metadata value. Returns the specified default value if no metadata was found...
std::string strMetadata(const std::string &name, const std::string &defaultVal) const
Tries to retrieve a string metadata value. Returns the specified default value if no metadata was fou...
float floatMetadata(const std::string &name, const float defaultVal) const
Tries to retrieve a float metadata value. Returns the specified default value if no metadata was foun...
void setFloatMetadata(const std::string &name, const float val)
Set the a float value for the given metadata name.
void setMapping(FieldMapping::Ptr mapping)
Sets the field's mapping.
Definition Field.h:347
boost::intrusive_ptr< FieldRes > Ptr
Definition Field.h:213
FieldMapping::Ptr mapping()
Returns a pointer to the mapping.
Definition Field.h:263
std::vector< Ptr > Vec
This is a convenience typedef for the list that Field3DInputFile::readScalarLayers() and Field3DInput...
Definition Field.h:403
boost::intrusive_ptr< Field > Ptr
Definition Field.h:395
std::string name
The name of the layer (always available)
std::string parent
The name of the parent partition. We need this in order to open its group.
boost::shared_ptr< OgOGroup > m_group
Group representing the partition.
LayerList m_layers
The layers belonging to this partition.
std::string name
Name of the partition.
void setGroup(boost::shared_ptr< OgOGroup > ptr)
Sets the group pointer.
virtual std::string className() const
void getLayerNames(std::vector< std::string > &names) const
Gets all the layer names.
OgOGroup & group() const
Returns a reference to the OgOGroup.
boost::intrusive_ptr< Partition > Ptr
const File::Layer * layer(const std::string &name) const
Finds a layer.
void addLayer(const File::Layer &layer)
Adds a layer.
Scoped object - creates a group on creation and closes it on destruction.
Definition Hdf5Util.h:166
void setSize(const V3i &size)
Resizes the object.
Definition Field.h:913
Namespace for Exception objects.
Definition Exception.h:57
Namespace for file I/O specifics.
Definition Field3DFile.h:87
Contains utility functions and classes for Hdf5 files.
Definition Hdf5Util.h:86
@ SevWarning
Definition Log.h:68
FIELD3D_API void print(Severity severity, const std::string &message)
Sends the string to the assigned output, prefixing the message with the severity.
Definition Log.cpp:70
#define FIELD3D_MAJOR_VER
Definition ns.h:38
#define FIELD3D_API
Definition ns.h:77
#define FIELD3D_NAMESPACE_SOURCE_CLOSE
Definition ns.h:60
#define FIELD3D_MINOR_VER
Definition ns.h:39
#define FIELD3D_MICRO_VER
Definition ns.h:40