diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H index 3bbc92855e52f4c6c21b7be82807c7553582b44a..e7feca1f9009f5e25c6c6b35ed752f37a462c0b4 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCore.H @@ -160,13 +160,59 @@ public: const std::string& datasetName ); + //- Add names to array selection + template<class StringType> + static label addToArray + ( + vtkDataArraySelection* select, + const std::string& prefix, + const UList<StringType>& names + ); + + //- Add names to array selection + template<class StringType> + static label addToArray + ( + vtkDataArraySelection* select, + const UList<StringType>& names, + const std::string& suffix = string::null + ); + + //- Add objects of Type to array selection + template<class Type> + static label addToSelection + ( + vtkDataArraySelection* select, + const std::string& prefix, + const IOobjectList& objects + ); + //- Add objects of Type to array selection template<class Type> static label addToSelection ( vtkDataArraySelection* select, const IOobjectList& objects, - const std::string& prefix = string::null + const std::string& suffix = string::null + ); + + //- Add objects of Type to array selection + template<class Type> + static label addToSelection + ( + vtkDataArraySelection* select, + const std::string& prefix, + const HashTable<wordHashSet>& objects + ); + + + //- Add objects of Type to array selection + template<class Type> + static label addToSelection + ( + vtkDataArraySelection* select, + const HashTable<wordHashSet>& objects, + const std::string& suffix = string::null ); diff --git a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C index 54eeee88c09bb8d06756afcade39996a2c85f461..cd9e2302b23d80aa907e3b197081ae550463ff36 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/foamPv/foamPvCoreTemplates.C @@ -28,25 +28,53 @@ License // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * // -template<class Type> -Foam::label Foam::foamPvCore::addToSelection +template<class StringType> +Foam::label Foam::foamPvCore::addToArray ( vtkDataArraySelection *select, - const IOobjectList& objects, - const std::string& prefix + const std::string& prefix, + const UList<StringType>& names ) { - const wordList names = objects.sortedNames(Type::typeName); + if (prefix.empty()) + { + for (const auto& name : names) + { + select->AddArray(name.c_str()); + } + } + else + { + for (const auto& name : names) + { + select->AddArray((prefix + name).c_str()); + } + } + + return names.size(); +} + - forAll(names, i) +template<class StringType> +Foam::label Foam::foamPvCore::addToArray +( + vtkDataArraySelection *select, + const UList<StringType>& names, + const std::string& suffix +) +{ + if (suffix.empty()) { - if (prefix.empty()) + for (const auto& name : names) { - select->AddArray(names[i].c_str()); + select->AddArray(name.c_str()); } - else + } + else + { + for (const auto& name : names) { - select->AddArray((prefix + names[i]).c_str()); + select->AddArray((name + suffix).c_str()); } } @@ -54,6 +82,68 @@ Foam::label Foam::foamPvCore::addToSelection } +template<class Type> +Foam::label Foam::foamPvCore::addToSelection +( + vtkDataArraySelection *select, + const std::string& prefix, + const IOobjectList& objects +) +{ + return addToArray(select, prefix, objects.sortedNames(Type::typeName)); +} + + +template<class Type> +Foam::label Foam::foamPvCore::addToSelection +( + vtkDataArraySelection *select, + const IOobjectList& objects, + const std::string& suffix +) +{ + return addToArray(select, objects.sortedNames(Type::typeName), suffix); +} + + +template<class Type> +Foam::label Foam::foamPvCore::addToSelection +( + vtkDataArraySelection *select, + const std::string& prefix, + const HashTable<wordHashSet>& objects +) +{ + auto iter = objects.cfind(Type::typeName); + + if (iter.found()) + { + return addToArray(select, prefix, iter.object().sortedToc()); + } + + return 0; +} + + +template<class Type> +Foam::label Foam::foamPvCore::addToSelection +( + vtkDataArraySelection *select, + const HashTable<wordHashSet>& objects, + const std::string& suffix +) +{ + auto iter = objects.cfind(Type::typeName); + + if (iter.found()) + { + return addToArray(select, iter.object().sortedToc(), suffix); + } + + return 0; +} + + template<class AnyValue, class AnyHasher> void Foam::foamPvCore::setSelectedArrayEntries ( diff --git a/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoam.H b/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoam.H index 55ec9d73e1e3916ea309d99687662028d039e677..226ff6b9bdb9c92a736c7fe15c0c7d8d9003be8b 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoam.H +++ b/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoam.H @@ -155,7 +155,10 @@ class vtkPVFoam vtkSmartPointer<dataType> getCopy() const { auto copy = vtkSmartPointer<dataType>::New(); - copy->ShallowCopy(vtkgeom); + if (vtkgeom) + { + copy->ShallowCopy(vtkgeom); + } return copy; } @@ -163,7 +166,10 @@ class vtkPVFoam void reuse() { dataset = vtkSmartPointer<dataType>::New(); - dataset->ShallowCopy(vtkgeom); + if (vtkgeom) + { + dataset->ShallowCopy(vtkgeom); + } } //- Set the geometry and make a shallow copy to dataset diff --git a/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoamUpdateInfo.C b/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoamUpdateInfo.C index 335a975fc84cb9da27298383c56ebc5ee4f4e5b2..9e61618cab65c5488fd357c7a7bd8e090b52297f 100644 --- a/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoamUpdateInfo.C +++ b/applications/utilities/postProcessing/graphics/PVReaders/vtkPVFoam/vtkPVFoamUpdateInfo.C @@ -85,11 +85,11 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames wordList names(zmesh.size()); label nZone = 0; - forAll(zmesh, zonei) + for (const auto& zn : zmesh) { - if (!zmesh[zonei].empty()) + if (!zn.empty()) { - names[nZone++] = zmesh[zonei].name(); + names[nZone++] = zn.name(); } } names.setSize(nZone); @@ -100,8 +100,6 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames Foam::wordList Foam::vtkPVFoam::getZoneNames(const word& zoneType) const { - wordList names; - // mesh not loaded - read from file IOobject ioObj ( @@ -119,14 +117,17 @@ Foam::wordList Foam::vtkPVFoam::getZoneNames(const word& zoneType) const false ); + wordList names; if (ioObj.typeHeaderOk<cellZoneMesh>(false, false)) { zonesEntries zones(ioObj); names.setSize(zones.size()); - forAll(zones, zonei) + label nZone = 0; + + for (const auto& zn : zones) { - names[zonei] = zones[zonei].keyword(); + names[nZone++] = zn.keyword(); } } @@ -167,7 +168,7 @@ void Foam::vtkPVFoam::updateInfoLagrangian << " " << dbPtr_->timePath()/cloud::prefix << endl; } - // use the db directly since this might be called without a mesh, + // Use the db directly since this might be called without a mesh, // but the region must get added back in fileName lagrangianPrefix(cloud::prefix); if (meshRegion_ != polyMesh::defaultRegion) @@ -175,23 +176,24 @@ void Foam::vtkPVFoam::updateInfoLagrangian lagrangianPrefix = meshRegion_/cloud::prefix; } - // Search for list of lagrangian objects for this time - fileNameList cloudDirs - ( - readDir(dbPtr_->timePath()/lagrangianPrefix, fileName::DIRECTORY) - ); + // List of lagrangian objects across all times + HashSet<fileName> names; - rangeLagrangian_.reset(select->GetNumberOfArrays()); - forAll(cloudDirs, cloudi) + for (const instant& t : dbPtr_().times()) { - // Add cloud to GUI list - select->AddArray + names.insert ( - ("lagrangian/" + cloudDirs[cloudi]).c_str() + readDir + ( + dbPtr_->path()/t.name()/lagrangianPrefix, + fileName::DIRECTORY + ) ); - ++rangeLagrangian_; } + rangeLagrangian_.reset(select->GetNumberOfArrays()); + rangeLagrangian_ += addToArray(select, "lagrangian/", names.sortedToc()); + if (debug) { Info<< "<end> " << FUNCTION_NAME << endl; @@ -257,39 +259,26 @@ void Foam::vtkPVFoam::updateInfoPatches const polyPatch& pp = patches[patchId]; if (pp.size()) { - enabledEntries.insert - ( - "patch/" + pp.name() - ); + enabledEntries.insert("patch/" + pp.name()); } } } } - // Sort group names - Foam::sort(displayNames); - for (const auto& name : displayNames) - { - select->AddArray(name.c_str()); - ++rangePatches_; - } + Foam::sort(displayNames); // Sorted group names + rangePatches_ += addToArray(select, displayNames); // Add (non-zero) patches to the list of mesh parts // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ if (!reader_->GetShowGroupsOnly()) { - forAll(patches, patchi) + for (const polyPatch& pp : patches) { - const polyPatch& pp = patches[patchi]; - if (pp.size()) { // Add patch to GUI list - select->AddArray - ( - ("patch/" + pp.name()).c_str() - ); + select->AddArray(("patch/" + pp.name()).c_str()); ++rangePatches_; } } @@ -339,9 +328,9 @@ void Foam::vtkPVFoam::updateInfoPatches && patchDict.readIfPresent("inGroups", groupNames) ) { - forAll(groupNames, groupI) + for (const auto& groupName : groupNames) { - groups(groupNames[groupI]).insert(patchi); + groups(groupName).insert(patchi); } } } @@ -370,21 +359,13 @@ void Foam::vtkPVFoam::updateInfoPatches { for (auto patchId : patchIDs) { - enabledEntries.insert - ( - "patch/" + names[patchId] - ); + enabledEntries.insert("patch/" + names[patchId]); } } } - // Sort group names - Foam::sort(displayNames); - for (const auto& name : displayNames) - { - select->AddArray(name.c_str()); - ++rangePatches_; - } + Foam::sort(displayNames); // Sorted group names + rangePatches_ += addToArray(select, displayNames); // Add (non-zero) patches to the list of mesh parts // ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -396,10 +377,7 @@ void Foam::vtkPVFoam::updateInfoPatches // Valid patch if nFace > 0 - add patch to GUI list if (sizes[patchi]) { - select->AddArray - ( - ("patch/" + names[patchi]).c_str() - ); + select->AddArray(("patch/" + names[patchi]).c_str()); ++rangePatches_; } } @@ -430,74 +408,44 @@ void Foam::vtkPVFoam::updateInfoZones << " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl; } - wordList namesLst; - // - // cellZones information - // ~~~~~~~~~~~~~~~~~~~~~ - if (meshPtr_) + // cellZones { - namesLst = getZoneNames(meshPtr_->cellZones()); - } - else - { - namesLst = getZoneNames("cellZones"); - } - - rangeCellZones_.reset(select->GetNumberOfArrays()); - forAll(namesLst, elemI) - { - select->AddArray + const wordList names = ( - ("cellZone/" + namesLst[elemI]).c_str() + meshPtr_ + ? getZoneNames(meshPtr_->cellZones()) + : getZoneNames("cellZones") ); - ++rangeCellZones_; - } - - // - // faceZones information - // ~~~~~~~~~~~~~~~~~~~~~ - if (meshPtr_) - { - namesLst = getZoneNames(meshPtr_->faceZones()); - } - else - { - namesLst = getZoneNames("faceZones"); + rangeCellZones_.reset(select->GetNumberOfArrays()); + rangeCellZones_ += addToArray(select, "cellZone/", names); } - rangeFaceZones_.reset(select->GetNumberOfArrays()); - forAll(namesLst, elemI) + // faceZones { - select->AddArray + const wordList names = ( - ("faceZone/" + namesLst[elemI]).c_str() + meshPtr_ + ? getZoneNames(meshPtr_->faceZones()) + : getZoneNames("faceZones") ); - ++rangeFaceZones_; - } - - // - // pointZones information - // ~~~~~~~~~~~~~~~~~~~~~~ - if (meshPtr_) - { - namesLst = getZoneNames(meshPtr_->pointZones()); - } - else - { - namesLst = getZoneNames("pointZones"); + rangeFaceZones_.reset(select->GetNumberOfArrays()); + rangeFaceZones_ += addToArray(select, "faceZone/", names); } - rangePointZones_.reset(select->GetNumberOfArrays()); - forAll(namesLst, elemI) + // pointZones { - select->AddArray + const wordList names = ( - ("pointZone/" + namesLst[elemI]).c_str() + meshPtr_ + ? getZoneNames(meshPtr_->pointZones()) + : getZoneNames("pointZones") ); - ++rangePointZones_; + + rangePointZones_.reset(select->GetNumberOfArrays()); + rangePointZones_ += addToArray(select, "pointZone/", names); } if (debug) @@ -525,14 +473,14 @@ void Foam::vtkPVFoam::updateInfoSets // Add names of sets. Search for last time directory with a sets // subdirectory. Take care not to search beyond the last mesh. - word facesInstance = dbPtr_().findInstance + const word facesInstance = dbPtr_().findInstance ( meshDir_, "faces", IOobject::READ_IF_PRESENT ); - word setsInstance = dbPtr_().findInstance + const word setsInstance = dbPtr_().findInstance ( meshDir_/"sets", word::null, @@ -540,7 +488,7 @@ void Foam::vtkPVFoam::updateInfoSets facesInstance ); - IOobjectList objects(dbPtr_(), setsInstance, meshDir_/"sets"); + const IOobjectList objects(dbPtr_(), setsInstance, meshDir_/"sets"); if (debug) { @@ -553,24 +501,24 @@ void Foam::vtkPVFoam::updateInfoSets rangeCellSets_ += addToSelection<cellSet> ( select, - objects, - "cellSet/" + "cellSet/", + objects ); rangeFaceSets_.reset(select->GetNumberOfArrays()); rangeFaceSets_ += addToSelection<faceSet> ( select, - objects, - "faceSet/" + "faceSet/", + objects ); rangePointSets_.reset(select->GetNumberOfArrays()); rangePointSets_ += addToSelection<pointSet> ( select, - objects, - "pointSet/" + "pointSet/", + objects ); if (debug) @@ -594,21 +542,20 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields HashSet<string> enabled = getSelectedArraySet(select); select->RemoveAllArrays(); - // TODO - currently only get fields from ONE cloud - // have to decide if the second set of fields get mixed in - // or dealt with separately - const arrayRange& range = rangeLagrangian_; if (range.empty()) { return; } - // Add Lagrangian fields even if particles are not enabled? - const int partId = range.start(); - const word cloudName = getReaderPartName(partId); + // Reuse the previously determined cloud information. + DynamicList<word> cloudNames(range.size()); + for (auto partId : range) + { + cloudNames.append(getReaderPartName(partId)); + } - // use the db directly since this might be called without a mesh, + // Use the db directly since this might be called without a mesh, // but the region must get added back in fileName lagrangianPrefix(cloud::prefix); if (meshRegion_ != polyMesh::defaultRegion) @@ -616,19 +563,37 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields lagrangianPrefix = meshRegion_/cloud::prefix; } - IOobjectList objects - ( - dbPtr_(), - dbPtr_().timeName(), - lagrangianPrefix/cloudName - ); + // List of lagrangian fields across all clouds and all times. + // ParaView displays "(partial)" after field names that only apply + // to some of the clouds. + HashTable<wordHashSet> fields; + + for (const instant& t : dbPtr_().times()) + { + for (const auto& cloudName : cloudNames) + { + const HashTable<wordHashSet> localFields = + IOobjectList + ( + dbPtr_(), + t.name(), + lagrangianPrefix/cloudName + ).classes(); + + forAllConstIters(localFields, iter) + { + fields(iter.key()) |= iter.object(); + } + } + } - addToSelection<IOField<label>>(select, objects); - addToSelection<IOField<scalar>>(select, objects); - addToSelection<IOField<vector>>(select, objects); - addToSelection<IOField<sphericalTensor>>(select, objects); - addToSelection<IOField<symmTensor>>(select, objects); - addToSelection<IOField<tensor>>(select, objects); + // Known/supported field-types + addToSelection<IOField<label>>(select, fields); + addToSelection<IOField<scalar>>(select, fields); + addToSelection<IOField<vector>>(select, fields); + addToSelection<IOField<sphericalTensor>>(select, fields); + addToSelection<IOField<symmTensor>>(select, fields); + addToSelection<IOField<tensor>>(select, fields); // Restore the enabled selections setSelectedArrayEntries(select, enabled);