mirror of
https://develop.openfoam.com/Development/openfoam.git
synced 2025-11-28 03:28:01 +00:00
ENH: paraview reader module with internal caching of the vtk geometries
- The reader module allows two levels of caching. The OpenFOAM fvMesh can be cached in memory, for faster loading of fields. Additionally, the translated VTK geometries are held in a local cache. The cached VTK geometries should incur no additional overhead since they use the VTK reference counting for their storage management.
This commit is contained in:
@ -27,6 +27,8 @@
|
||||
</Documentation>
|
||||
</DoubleVectorProperty>
|
||||
|
||||
<!-- General Controls -->
|
||||
|
||||
<!-- Refresh (push button) -->
|
||||
<Property
|
||||
name="Refresh"
|
||||
@ -35,12 +37,10 @@
|
||||
<Documentation>Rescan for updated times/fields.</Documentation>
|
||||
</Property>
|
||||
|
||||
<!-- General Controls -->
|
||||
|
||||
<!-- Skip Zero Time (check-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="ZeroTime"
|
||||
label="Skip Zero Time"
|
||||
label="Skip 0/ time"
|
||||
command="SetSkipZeroTime"
|
||||
default_values="1"
|
||||
number_of_elements="1"
|
||||
@ -54,26 +54,28 @@
|
||||
<!-- Include Sets (check-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="IncludeSets"
|
||||
label="With Sets"
|
||||
command="SetIncludeSets"
|
||||
default_values="0"
|
||||
number_of_elements="1"
|
||||
panel_visibility="default">
|
||||
<BooleanDomain name="bool"/>
|
||||
<Documentation>
|
||||
Search the polyMesh/sets/ directory
|
||||
Search the polyMesh/sets/ directory for {cell,face,point} sets
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
|
||||
<!-- Include Zones (check-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="IncludeZones"
|
||||
label="With Zones"
|
||||
command="SetIncludeZones"
|
||||
default_values="0"
|
||||
number_of_elements="1"
|
||||
panel_visibility="default">
|
||||
<BooleanDomain name="bool"/>
|
||||
<Documentation>
|
||||
ZoneMesh information is used to find {cell,face,point}Zones.
|
||||
ZoneMesh information is used to find {cell,face,point} zones.
|
||||
The polyMesh/ directory is only checked on startup.
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
@ -88,7 +90,7 @@
|
||||
panel_visibility="default">
|
||||
<BooleanDomain name="bool"/>
|
||||
<Documentation>
|
||||
Show patchGroups only.
|
||||
Display patchGroups only instead of individual patches.
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
|
||||
@ -109,6 +111,7 @@
|
||||
<!-- Interpolate Fields (check-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="InterpolateFields"
|
||||
label="cell-to-point"
|
||||
command="SetInterpolateVolFields"
|
||||
default_values="1"
|
||||
number_of_elements="1"
|
||||
@ -122,6 +125,7 @@
|
||||
<!-- Extrapolate Patches (check-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="ExtrapolatePatches"
|
||||
label="field-to-patch"
|
||||
command="SetExtrapolatePatches"
|
||||
default_values="0"
|
||||
number_of_elements="1"
|
||||
@ -132,7 +136,7 @@
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
|
||||
<!-- Force GUI update (check-box) -->
|
||||
<!-- Force GUI update (push button) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="UpdateGUI"
|
||||
command="SetUpdateGUI"
|
||||
@ -159,16 +163,22 @@
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
|
||||
<!-- Cache Mesh (check-box) -->
|
||||
<!-- Mesh Caching (combo-box) -->
|
||||
<IntVectorProperty animateable="0"
|
||||
name="CacheMesh"
|
||||
command="SetCacheMesh"
|
||||
default_values="1"
|
||||
name="MeshCaching"
|
||||
command="SetMeshCaching"
|
||||
default_values="3"
|
||||
number_of_elements="1"
|
||||
panel_visibility="default">
|
||||
<BooleanDomain name="bool"/>
|
||||
<EnumerationDomain name="enum">
|
||||
<Entry text="No caching" value="0" />
|
||||
<Entry text="Cache fvMesh" value="1" />
|
||||
<Entry text="Cache vtk,fvMesh" value="3" />
|
||||
</EnumerationDomain>
|
||||
<Documentation>
|
||||
Cache the fvMesh in memory.
|
||||
Mesh caching styles.
|
||||
Caching the OpenFOAM fvMesh reduces disk access.
|
||||
Caching the VTK mesh reduces transcription overhead.
|
||||
</Documentation>
|
||||
</IntVectorProperty>
|
||||
|
||||
@ -185,7 +195,7 @@
|
||||
<Property name="ShowPatchNames"/>
|
||||
<Property name="UpdateGUI"/>
|
||||
<Property name="UseVTKPolyhedron"/>
|
||||
<Property name="CacheMesh"/>
|
||||
<Property name="MeshCaching"/>
|
||||
</PropertyGroup>
|
||||
|
||||
<!-- Parts Selections -->
|
||||
|
||||
@ -26,6 +26,7 @@ License
|
||||
#include "pqFoamReaderControls.h"
|
||||
|
||||
#include <QCheckBox>
|
||||
#include <QComboBox>
|
||||
#include <QFrame>
|
||||
#include <QGridLayout>
|
||||
#include <QPushButton>
|
||||
@ -42,6 +43,17 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
// file-scope
|
||||
// Add horizontal divider to layout
|
||||
static void addHline(QGridLayout* layout, int row, int nCols)
|
||||
{
|
||||
QFrame* hline = new QFrame(layout->parentWidget());
|
||||
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
|
||||
|
||||
layout->addWidget(hline, row, 0, 1, nCols);
|
||||
}
|
||||
|
||||
|
||||
// file-scope
|
||||
// Widget properties
|
||||
static QWidget* setWidgetProperties
|
||||
@ -94,6 +106,66 @@ static QAbstractButton* setButtonProperties
|
||||
}
|
||||
|
||||
|
||||
// file-scope
|
||||
// Fill combo-box from XML enumeration
|
||||
static QComboBox* setComboBoxContent
|
||||
(
|
||||
QComboBox* b,
|
||||
vtkSMIntVectorProperty* prop
|
||||
)
|
||||
{
|
||||
vtkSMEnumerationDomain* propEnum =
|
||||
vtkSMEnumerationDomain::SafeDownCast
|
||||
(
|
||||
prop->FindDomain("vtkSMEnumerationDomain")
|
||||
);
|
||||
|
||||
if (propEnum)
|
||||
{
|
||||
unsigned int n = propEnum->GetNumberOfEntries();
|
||||
for (unsigned int idx=0; idx < n; ++idx)
|
||||
{
|
||||
const int val = propEnum->GetEntryValue(idx);
|
||||
const char* txt = propEnum->GetEntryText(idx);
|
||||
|
||||
b->insertItem(val, txt);
|
||||
}
|
||||
|
||||
// Set default
|
||||
const int val = prop->GetElement(0);
|
||||
unsigned int idx = 0;
|
||||
if (!propEnum->IsInDomain(val, idx))
|
||||
{
|
||||
idx = 0;
|
||||
}
|
||||
b->setCurrentIndex(idx);
|
||||
}
|
||||
|
||||
return b;
|
||||
}
|
||||
|
||||
|
||||
// file-scope
|
||||
// Translate a combo-box index to a lookup value
|
||||
static int comboBoxValue(vtkSMIntVectorProperty* prop, int idx)
|
||||
{
|
||||
vtkSMEnumerationDomain* propEnum =
|
||||
vtkSMEnumerationDomain::SafeDownCast
|
||||
(
|
||||
prop->FindDomain("vtkSMEnumerationDomain")
|
||||
);
|
||||
|
||||
if (propEnum)
|
||||
{
|
||||
return propEnum->GetEntryValue(idx);
|
||||
}
|
||||
else
|
||||
{
|
||||
return idx;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static vtkSMIntVectorProperty* lookupIntProp
|
||||
(
|
||||
vtkSMPropertyGroup* group,
|
||||
@ -154,9 +226,9 @@ void pqFoamReaderControls::refreshPressed()
|
||||
}
|
||||
|
||||
|
||||
void pqFoamReaderControls::cacheMesh(int val)
|
||||
void pqFoamReaderControls::cacheMesh(int idx)
|
||||
{
|
||||
fireCommand(cacheMesh_, val);
|
||||
fireCommand(meshCaching_, comboBoxValue(meshCaching_, idx));
|
||||
}
|
||||
|
||||
|
||||
@ -210,12 +282,14 @@ pqFoamReaderControls::pqFoamReaderControls
|
||||
showGroupsOnly_(lookupIntProp(group, "ShowGroupsOnly")),
|
||||
includeSets_(lookupIntProp(group, "IncludeSets")),
|
||||
includeZones_(lookupIntProp(group, "IncludeZones")),
|
||||
cacheMesh_(lookupIntProp(group, "CacheMesh"))
|
||||
meshCaching_(lookupIntProp(group, "MeshCaching"))
|
||||
{
|
||||
typedef vtkSMIntVectorProperty intProp;
|
||||
|
||||
QGridLayout* form = new QGridLayout(this);
|
||||
|
||||
const int nCols = 3;
|
||||
|
||||
// ROW
|
||||
// ~~~
|
||||
int row = 0;
|
||||
@ -243,13 +317,7 @@ pqFoamReaderControls::pqFoamReaderControls
|
||||
}
|
||||
|
||||
// LINE
|
||||
// ~~~~
|
||||
++row;
|
||||
{
|
||||
QFrame* hline = new QFrame(this);
|
||||
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
|
||||
form->addWidget(hline, row, 0, 1, 4);
|
||||
}
|
||||
addHline(form, ++row, nCols);
|
||||
|
||||
// ROW
|
||||
// ~~~
|
||||
@ -321,13 +389,7 @@ pqFoamReaderControls::pqFoamReaderControls
|
||||
}
|
||||
|
||||
// LINE
|
||||
// ~~~~
|
||||
++row;
|
||||
{
|
||||
QFrame* hline = new QFrame(this);
|
||||
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
|
||||
form->addWidget(hline, row, 0, 1, 4);
|
||||
}
|
||||
addHline(form, ++row, nCols);
|
||||
|
||||
// ROW
|
||||
// ~~~
|
||||
@ -360,13 +422,7 @@ pqFoamReaderControls::pqFoamReaderControls
|
||||
}
|
||||
|
||||
// LINE
|
||||
// ~~~~
|
||||
++row;
|
||||
{
|
||||
QFrame* hline = new QFrame(this);
|
||||
hline->setFrameStyle(QFrame::HLine | QFrame::Sunken);
|
||||
form->addWidget(hline, row, 0, 1, 4);
|
||||
}
|
||||
addHline(form, ++row, nCols);
|
||||
|
||||
// ROW
|
||||
// ~~~
|
||||
@ -398,14 +454,22 @@ pqFoamReaderControls::pqFoamReaderControls
|
||||
);
|
||||
}
|
||||
|
||||
if (cacheMesh_)
|
||||
if (meshCaching_)
|
||||
{
|
||||
QCheckBox* b = new QCheckBox(this);
|
||||
setButtonProperties(b, cacheMesh_);
|
||||
QComboBox* b = new QComboBox(this);
|
||||
form->addWidget(b, row, 2, Qt::AlignLeft);
|
||||
|
||||
setWidgetProperties(b, meshCaching_);
|
||||
setComboBoxContent(b, meshCaching_);
|
||||
|
||||
addPropertyLink
|
||||
(
|
||||
b, "indexChanged", SIGNAL(currentIndexChanged(int)), meshCaching_
|
||||
);
|
||||
|
||||
connect
|
||||
(
|
||||
b, SIGNAL(toggled(bool)), this, SLOT(cacheMesh(bool))
|
||||
b, SIGNAL(currentIndexChanged(int)), this, SLOT(cacheMesh(int))
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -69,8 +69,8 @@ class pqFoamReaderControls
|
||||
//- IncludeZones (bool property)
|
||||
vtkSMIntVectorProperty* includeZones_;
|
||||
|
||||
//- CacheMesh (bool property)
|
||||
vtkSMIntVectorProperty* cacheMesh_;
|
||||
//- MeshCaching (enum property)
|
||||
vtkSMIntVectorProperty* meshCaching_;
|
||||
|
||||
|
||||
// Private Member Functions
|
||||
@ -102,7 +102,7 @@ protected slots:
|
||||
// Protected Member Functions
|
||||
|
||||
void refreshPressed();
|
||||
void cacheMesh(bool checked);
|
||||
void cacheMesh(int idx);
|
||||
void showPatchNames(bool checked);
|
||||
void showGroupsOnly(bool checked);
|
||||
void includeSets(bool checked);
|
||||
|
||||
@ -69,8 +69,7 @@ vtkPVFoamReader::vtkPVFoamReader()
|
||||
// Add second output for the Lagrangian
|
||||
this->SetNumberOfOutputPorts(2);
|
||||
|
||||
vtkSmartPointer<vtkMultiBlockDataSet> lagrangian =
|
||||
vtkSmartPointer<vtkMultiBlockDataSet>::New();
|
||||
auto lagrangian = vtkSmartPointer<vtkMultiBlockDataSet>::New();
|
||||
|
||||
lagrangian->ReleaseData();
|
||||
|
||||
@ -80,7 +79,7 @@ vtkPVFoamReader::vtkPVFoamReader()
|
||||
TimeStepRange[0] = 0;
|
||||
TimeStepRange[1] = 0;
|
||||
|
||||
CacheMesh = true;
|
||||
MeshCaching = 3; // fvMesh+vtk
|
||||
|
||||
SkipZeroTime = true;
|
||||
ExtrapolatePatches = false;
|
||||
|
||||
@ -83,9 +83,9 @@ public:
|
||||
virtual void PrintInfo();
|
||||
|
||||
// Description:
|
||||
// OpenFOAM mesh caching control
|
||||
vtkSetMacro(CacheMesh, bool);
|
||||
vtkGetMacro(CacheMesh, bool);
|
||||
// Mesh caching control (0:none,1:fvMesh,3:fvMesh+vtk)
|
||||
vtkSetMacro(MeshCaching, int);
|
||||
vtkGetMacro(MeshCaching, int);
|
||||
|
||||
// Description:
|
||||
// OpenFOAM refresh times/fields
|
||||
@ -232,7 +232,7 @@ private:
|
||||
void updatePatchNamesView(const bool show);
|
||||
|
||||
int TimeStepRange[2];
|
||||
bool CacheMesh;
|
||||
int MeshCaching;
|
||||
bool SkipZeroTime;
|
||||
|
||||
bool ExtrapolatePatches;
|
||||
|
||||
@ -136,12 +136,12 @@ bool Foam::vtkPVFoam::addOutputBlock
|
||||
if (selectedPartIds_.found(partId))
|
||||
{
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word shortName = getPartName(partId);
|
||||
const word shortName = getFoamName(longName);
|
||||
|
||||
auto iter = cache.find(longName);
|
||||
if (iter.found() && (*iter).vtkmesh)
|
||||
if (iter.found() && iter.object().dataset)
|
||||
{
|
||||
auto dataset = (*iter).vtkmesh;
|
||||
auto dataset = iter.object().dataset;
|
||||
|
||||
if (singleDataset)
|
||||
{
|
||||
@ -224,7 +224,6 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
|
||||
runTime.setTime(Times[nearestIndex], nearestIndex);
|
||||
|
||||
// When the changes, so do the fields
|
||||
fieldsChanged_ = true;
|
||||
meshState_ = meshPtr_ ? meshPtr_->readUpdate() : polyMesh::TOPO_CHANGE;
|
||||
|
||||
reader_->UpdateProgress(0.05);
|
||||
@ -238,27 +237,13 @@ int Foam::vtkPVFoam::setTime(int nRequest, const double requestTimes[])
|
||||
Info<< "<end> setTime() - selectedTime="
|
||||
<< Times[nearestIndex].name() << " index=" << timeIndex_
|
||||
<< "/" << Times.size()
|
||||
<< " meshUpdateState=" << updateStateName(meshState_)
|
||||
<< " fieldsChanged=" << Switch(fieldsChanged_) << endl;
|
||||
<< " meshUpdateState=" << updateStateName(meshState_) << endl;
|
||||
}
|
||||
|
||||
return nearestIndex;
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::vtkPVFoam::getPartName(const int partId) const
|
||||
{
|
||||
if (selectedPartIds_.found(partId))
|
||||
{
|
||||
return getFoamName(selectedPartIds_[partId]);
|
||||
}
|
||||
else
|
||||
{
|
||||
return word::null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Foam::word Foam::vtkPVFoam::getReaderPartName(const int partId) const
|
||||
{
|
||||
return getFoamName(reader_->GetPartArrayName(partId));
|
||||
@ -279,8 +264,8 @@ Foam::vtkPVFoam::vtkPVFoam
|
||||
meshRegion_(polyMesh::defaultRegion),
|
||||
meshDir_(polyMesh::meshSubDir),
|
||||
timeIndex_(-1),
|
||||
decomposePoly_(false),
|
||||
meshState_(polyMesh::TOPO_CHANGE),
|
||||
fieldsChanged_(true),
|
||||
rangeVolume_("unzoned"),
|
||||
rangePatches_("patch"),
|
||||
rangeLagrangian_("lagrangian"),
|
||||
@ -414,16 +399,16 @@ void Foam::vtkPVFoam::updateInfo()
|
||||
// time of the vtkDataArraySelection, but the qt/paraview proxy
|
||||
// layer doesn't care about that anyhow.
|
||||
|
||||
HashSet<string> enabledEntries;
|
||||
HashSet<string> enabled;
|
||||
if (!partSelection->GetNumberOfArrays() && !meshPtr_)
|
||||
{
|
||||
// enable 'internalMesh' on the first call
|
||||
enabledEntries = { "internalMesh" };
|
||||
// Fake enable 'internalMesh' on the first call
|
||||
enabled = { "internalMesh" };
|
||||
}
|
||||
else
|
||||
{
|
||||
// preserve the enabled selections
|
||||
enabledEntries = getSelectedArrayEntries(partSelection);
|
||||
enabled = getSelectedArraySet(partSelection);
|
||||
}
|
||||
|
||||
// Clear current mesh parts list
|
||||
@ -431,18 +416,13 @@ void Foam::vtkPVFoam::updateInfo()
|
||||
|
||||
// Update mesh parts list - add Lagrangian at the bottom
|
||||
updateInfoInternalMesh(partSelection);
|
||||
updateInfoPatches(partSelection, enabledEntries);
|
||||
updateInfoPatches(partSelection, enabled);
|
||||
updateInfoSets(partSelection);
|
||||
updateInfoZones(partSelection);
|
||||
updateInfoLagrangian(partSelection);
|
||||
|
||||
// Adjust/restore the enabled selections
|
||||
setSelectedArrayEntries(partSelection, enabledEntries);
|
||||
|
||||
if (meshState_ != polyMesh::UNCHANGED)
|
||||
{
|
||||
fieldsChanged_ = true;
|
||||
}
|
||||
setSelectedArrayEntries(partSelection, enabled);
|
||||
|
||||
// Update volume, point and lagrangian fields
|
||||
updateInfoFields<fvPatchField, volMesh>
|
||||
@ -480,42 +460,28 @@ void Foam::vtkPVFoam::Update
|
||||
}
|
||||
reader_->UpdateProgress(0.1);
|
||||
|
||||
const int caching = reader_->GetMeshCaching();
|
||||
const bool oldDecomp = decomposePoly_;
|
||||
decomposePoly_ = !reader_->GetUseVTKPolyhedron();
|
||||
|
||||
// Set up mesh parts selection(s)
|
||||
// Update cached, saved, unneed values.
|
||||
{
|
||||
vtkDataArraySelection* selection = reader_->GetPartSelection();
|
||||
const int n = selection->GetNumberOfArrays();
|
||||
|
||||
// All previously selected (enabled) names
|
||||
HashSet<string> original;
|
||||
forAllConstIters(selectedPartIds_, iter)
|
||||
{
|
||||
original.insert(iter.object());
|
||||
}
|
||||
|
||||
selectedPartIds_.clear();
|
||||
HashSet<string> nowActive;
|
||||
|
||||
for (int id=0; id < n; ++id)
|
||||
{
|
||||
string str(selection->GetArrayName(id));
|
||||
bool status = selection->GetArraySetting(id);
|
||||
const string str(selection->GetArrayName(id));
|
||||
const bool status = selection->GetArraySetting(id);
|
||||
|
||||
if (status)
|
||||
{
|
||||
selectedPartIds_.set(id, str); // id -> name
|
||||
|
||||
if (!original.erase(str))
|
||||
{
|
||||
// New part, or newly enabled
|
||||
//? meshChanged_ = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (original.erase(str))
|
||||
{
|
||||
// Part disappeared, or newly disabled
|
||||
//? meshChanged_ = true;
|
||||
}
|
||||
nowActive.set(str);
|
||||
}
|
||||
|
||||
if (debug > 1)
|
||||
@ -524,6 +490,39 @@ void Foam::vtkPVFoam::Update
|
||||
<< " : " << str << nl;
|
||||
}
|
||||
}
|
||||
|
||||
// Dispose of unneeded components
|
||||
cachedVtp_.retain(nowActive);
|
||||
cachedVtu_.retain(nowActive);
|
||||
|
||||
if
|
||||
(
|
||||
!caching
|
||||
|| meshState_ == polyMesh::TOPO_CHANGE
|
||||
|| meshState_ == polyMesh::TOPO_PATCH_CHANGE
|
||||
)
|
||||
{
|
||||
// Eliminate cached values that would be unreliable
|
||||
forAllIters(cachedVtp_, iter)
|
||||
{
|
||||
iter.object().clearGeom();
|
||||
iter.object().clear();
|
||||
}
|
||||
forAllIters(cachedVtu_, iter)
|
||||
{
|
||||
iter.object().clearGeom();
|
||||
iter.object().clear();
|
||||
}
|
||||
}
|
||||
else if (oldDecomp != decomposePoly_)
|
||||
{
|
||||
// poly-decompose changed - dispose of cached values
|
||||
forAllIters(cachedVtu_, iter)
|
||||
{
|
||||
iter.object().clearGeom();
|
||||
iter.object().clear();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reader_->UpdateProgress(0.15);
|
||||
@ -536,7 +535,7 @@ void Foam::vtkPVFoam::Update
|
||||
printMemory();
|
||||
}
|
||||
|
||||
if (!reader_->GetCacheMesh())
|
||||
if (!caching)
|
||||
{
|
||||
delete meshPtr_;
|
||||
meshPtr_ = nullptr;
|
||||
@ -549,7 +548,6 @@ void Foam::vtkPVFoam::Update
|
||||
{
|
||||
Info<< "Creating OpenFOAM mesh for region " << meshRegion_
|
||||
<< " at time=" << dbPtr_().timeName() << endl;
|
||||
|
||||
}
|
||||
|
||||
meshPtr_ = new fvMesh
|
||||
@ -582,17 +580,6 @@ void Foam::vtkPVFoam::Update
|
||||
|
||||
reader_->UpdateProgress(0.4);
|
||||
|
||||
// Update cached, saved, unneed values:
|
||||
HashSet<string> nowActive;
|
||||
forAllConstIters(selectedPartIds_, iter)
|
||||
{
|
||||
nowActive.insert(iter.object());
|
||||
}
|
||||
|
||||
// Dispose of unneeded components
|
||||
cachedVtp_.retain(nowActive);
|
||||
cachedVtu_.retain(nowActive);
|
||||
|
||||
convertMeshVolume();
|
||||
convertMeshPatches();
|
||||
reader_->UpdateProgress(0.6);
|
||||
@ -645,18 +632,28 @@ void Foam::vtkPVFoam::Update
|
||||
}
|
||||
reader_->UpdateProgress(0.95);
|
||||
|
||||
fieldsChanged_ = false;
|
||||
meshState_ = polyMesh::UNCHANGED;
|
||||
|
||||
// Standard memory cleanup
|
||||
if (caching & 2)
|
||||
{
|
||||
// Suppress caching of Lagrangian since it normally always changes.
|
||||
cachedVtp_.filterKeys
|
||||
(
|
||||
[](const word& k){ return k.startsWith("lagrangian/"); },
|
||||
true // prune
|
||||
);
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedVtp_.clear();
|
||||
cachedVtu_.clear();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtkPVFoam::UpdateFinalize()
|
||||
{
|
||||
if (!reader_->GetCacheMesh())
|
||||
if (!reader_->GetMeshCaching())
|
||||
{
|
||||
delete meshPtr_;
|
||||
meshPtr_ = nullptr;
|
||||
|
||||
@ -25,7 +25,25 @@ Class
|
||||
Foam::vtkPVFoam
|
||||
|
||||
Description
|
||||
Provides a reader interface for OpenFOAM to VTK interaction.
|
||||
The backend for the vtkPVFoamReader reader module -
|
||||
providing a paraview reader interface for OpenFOAM meshes and fields.
|
||||
|
||||
Similar, and sometimes better, functionality may be provided by the
|
||||
native VTK OpenFOAM reader. OpenCFD has recently (2017) been working
|
||||
on improving the native VTK OpenFOAM reader for the benefit of everyone.
|
||||
|
||||
In some areas the reader module lacks compared to the native reader
|
||||
(notably the ability to work on decomosed datasets), but provides
|
||||
additional handling of sets,zones,groups. Some features have also since
|
||||
been adapted to the native reader. Additionally, the reader module
|
||||
provides a useful platform for testing new ideas.
|
||||
|
||||
Note
|
||||
The reader module allows two levels of caching. The OpenFOAM fvMesh
|
||||
can be cached in memory, for faster loading of fields. Additionally,
|
||||
the translated VTK geometries are held in a local cache. The cached
|
||||
VTK geometries should incur no additional overhead since they use
|
||||
the VTK reference counting for their storage management.
|
||||
|
||||
SourceFiles
|
||||
vtkPVFoam.C
|
||||
@ -56,22 +74,22 @@ SourceFiles
|
||||
#include "foamPvCore.H"
|
||||
#include "foamVtkMeshMaps.H"
|
||||
|
||||
#include "vtkSmartPointer.h"
|
||||
#include "vtkPoints.h"
|
||||
#include "vtkPolyData.h"
|
||||
#include "vtkSmartPointer.h"
|
||||
#include "vtkUnstructuredGrid.h"
|
||||
|
||||
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * //
|
||||
|
||||
class vtkCellArray;
|
||||
class vtkDataArraySelection;
|
||||
class vtkDataSet;
|
||||
class vtkFloatArray;
|
||||
class vtkPoints;
|
||||
class vtkIndent;
|
||||
class vtkMultiBlockDataSet;
|
||||
class vtkPVFoamReader;
|
||||
class vtkRenderer;
|
||||
class vtkTextActor;
|
||||
class vtkMultiBlockDataSet;
|
||||
class vtkIndent;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -104,20 +122,99 @@ class vtkPVFoam
|
||||
|
||||
// Private classes
|
||||
|
||||
//- Bookkeeping for vtkPolyData
|
||||
class foamVtpData
|
||||
//- Bookkeeping for internal caching.
|
||||
// Retain an original copy of the geometry as well as a shallow copy
|
||||
// with the output fields.
|
||||
// The original copy is reused for different timestep
|
||||
template<class DataType>
|
||||
class foamVtkCaching
|
||||
{
|
||||
public:
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh;
|
||||
typedef DataType dataType;
|
||||
|
||||
//- The geometry, without any cell/point data
|
||||
vtkSmartPointer<dataType> vtkgeom;
|
||||
|
||||
//- The shallow-copy of geometry, plus additional data
|
||||
vtkSmartPointer<dataType> dataset;
|
||||
|
||||
//- Number of points associated with geometry
|
||||
inline uint64_t nPoints() const
|
||||
{
|
||||
return vtkgeom ? vtkgeom->GetNumberOfPoints() : 0;
|
||||
}
|
||||
|
||||
//- Clear geometry and dataset
|
||||
void clearGeom()
|
||||
{
|
||||
vtkgeom = nullptr;
|
||||
dataset = nullptr;
|
||||
}
|
||||
|
||||
//- Return a shallow copy of vtkgeom for manipulation
|
||||
vtkSmartPointer<dataType> getCopy() const
|
||||
{
|
||||
auto copy = vtkSmartPointer<dataType>::New();
|
||||
copy->ShallowCopy(vtkgeom);
|
||||
return copy;
|
||||
}
|
||||
|
||||
//- Make a shallow copy of vtkgeom into dataset
|
||||
void reuse()
|
||||
{
|
||||
dataset = vtkSmartPointer<dataType>::New();
|
||||
dataset->ShallowCopy(vtkgeom);
|
||||
}
|
||||
|
||||
//- Set the geometry and make a shallow copy to dataset
|
||||
void set(vtkSmartPointer<dataType> geom)
|
||||
{
|
||||
vtkgeom = geom;
|
||||
reuse();
|
||||
}
|
||||
|
||||
//- Report basic information to output
|
||||
void PrintSelf(std::ostream& os) const
|
||||
{
|
||||
os << "geom" << nl;
|
||||
if (vtkgeom)
|
||||
{
|
||||
vtkgeom->PrintSelf(std::cout, vtkIndent(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "nullptr";
|
||||
}
|
||||
os << nl;
|
||||
|
||||
os << "copy" << nl;
|
||||
if (dataset)
|
||||
{
|
||||
dataset->PrintSelf(std::cout, vtkIndent(2));
|
||||
}
|
||||
else
|
||||
{
|
||||
os << "nullptr";
|
||||
}
|
||||
os << nl;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
//- Bookkeeping for vtkPolyData
|
||||
class foamVtpData
|
||||
:
|
||||
public foamVtkCaching<vtkPolyData>,
|
||||
public foamVtkMeshMaps
|
||||
{};
|
||||
|
||||
|
||||
//- Bookkeeping for vtkUnstructuredGrid
|
||||
class foamVtuData : public foamVtkMeshMaps
|
||||
{
|
||||
public:
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh;
|
||||
};
|
||||
class foamVtuData
|
||||
:
|
||||
public foamVtkCaching<vtkUnstructuredGrid>,
|
||||
public foamVtkMeshMaps
|
||||
{};
|
||||
|
||||
|
||||
// Private Data
|
||||
@ -140,12 +237,12 @@ class vtkPVFoam
|
||||
//- The time index
|
||||
int timeIndex_;
|
||||
|
||||
//- Previous/current decomposition request
|
||||
bool decomposePoly_;
|
||||
|
||||
//- Track changes in mesh geometry
|
||||
enum polyMesh::readUpdateState meshState_;
|
||||
|
||||
//- Track changes in fields
|
||||
bool fieldsChanged_;
|
||||
|
||||
//- The index of selected parts mapped to their names
|
||||
Map<string> selectedPartIds_;
|
||||
|
||||
@ -232,75 +329,143 @@ class vtkPVFoam
|
||||
|
||||
// Mesh conversion functions
|
||||
|
||||
//- Convert volume mesh
|
||||
//- Convert InternalMesh
|
||||
void convertMeshVolume();
|
||||
|
||||
//- Convert Lagrangian points
|
||||
void convertMeshLagrangian();
|
||||
|
||||
//- Convert mesh patches
|
||||
//- Convert mesh patches.
|
||||
// The additionalIds (cached data) contain the patch Ids.
|
||||
// There will be several for groups, but only one for regular patches.
|
||||
void convertMeshPatches();
|
||||
|
||||
//- Convert subsetted mesh
|
||||
void convertMeshSubset
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const string& longName
|
||||
);
|
||||
|
||||
//- Convert cell zones
|
||||
void convertMeshCellZones();
|
||||
|
||||
//- Convert face zones
|
||||
void convertMeshFaceZones();
|
||||
|
||||
//- Convert point zones
|
||||
void convertMeshPointZones();
|
||||
|
||||
//- Convert cell sets
|
||||
void convertMeshCellSets();
|
||||
|
||||
//- Convert face zones
|
||||
void convertMeshFaceZones();
|
||||
|
||||
//- Convert face sets
|
||||
// The cellMap (cached data) contains the face-labels.
|
||||
void convertMeshFaceSets();
|
||||
|
||||
//- Convert point zones
|
||||
// The pointMap (cached data) contains the point-labels.
|
||||
void convertMeshPointZones();
|
||||
|
||||
//- Convert point sets
|
||||
// The pointMap (cached data) contains the point-labels.
|
||||
void convertMeshPointSets();
|
||||
|
||||
|
||||
// Add mesh functions
|
||||
|
||||
//- Volume meshes as vtkUnstructuredGrid
|
||||
//- Generate vtk points for the current mesh points/decomposition
|
||||
static vtkSmartPointer<vtkPoints> movePoints
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtuData& vtuData
|
||||
);
|
||||
|
||||
//- Generate vtk points for the current mesh points/decomposition,
|
||||
// using the provided pointMap
|
||||
static vtkSmartPointer<vtkPoints> movePoints
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtuData& vtuData,
|
||||
const labelUList& pointMap
|
||||
);
|
||||
|
||||
//- Volume mesh as vtkUnstructuredGrid
|
||||
static vtkSmartPointer<vtkUnstructuredGrid> volumeVTKMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
foamVtuData& vtuData,
|
||||
const bool decompPoly
|
||||
);
|
||||
|
||||
//- Subsetted mesh as vtkUnstructuredGrid
|
||||
static vtkSmartPointer<vtkUnstructuredGrid> volumeVTKSubsetMesh
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
foamVtuData& vtuData,
|
||||
const bool decompPoly
|
||||
);
|
||||
|
||||
//- Volume mesh as vtkUnstructuredGrid
|
||||
vtkSmartPointer<vtkUnstructuredGrid> volumeVTKMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
foamVtuData& vtuData
|
||||
);
|
||||
) const;
|
||||
|
||||
//- Subsetted mesh as vtkUnstructuredGrid
|
||||
vtkSmartPointer<vtkUnstructuredGrid> volumeVTKSubsetMesh
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
foamVtuData& vtuData
|
||||
) const;
|
||||
|
||||
//- Lagrangian positions as vtkPolyData
|
||||
vtkSmartPointer<vtkPolyData> lagrangianVTKMesh
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& cloudName
|
||||
) const;
|
||||
|
||||
//- Patch points
|
||||
template<class PatchType>
|
||||
static vtkSmartPointer<vtkPoints> movePatchPoints
|
||||
(
|
||||
const PatchType& p
|
||||
);
|
||||
|
||||
//- Patch faces as vtk-cells
|
||||
template<class PatchType>
|
||||
static vtkSmartPointer<vtkCellArray> patchFacesVTKCells
|
||||
(
|
||||
const PatchType& p
|
||||
);
|
||||
|
||||
//- Patches (mesh or primitive) as vtkPolyData
|
||||
template<class PatchType>
|
||||
vtkSmartPointer<vtkPolyData> patchVTKMesh
|
||||
static vtkSmartPointer<vtkPolyData> patchVTKMesh
|
||||
(
|
||||
const string& name,
|
||||
const PatchType& p
|
||||
);
|
||||
|
||||
|
||||
// Field conversion functions
|
||||
|
||||
//- Convert Field to VTK field
|
||||
//- Copy list to pre-allocated vtk array.
|
||||
// \return number of input items copied
|
||||
template<class Type>
|
||||
static label transcribeFloatData
|
||||
(
|
||||
vtkFloatArray* array,
|
||||
const UList<Type>& input,
|
||||
const label start = 0
|
||||
);
|
||||
|
||||
//- Create named field initialized to zero
|
||||
template<class Type>
|
||||
static vtkSmartPointer<vtkFloatArray> zeroVTKField
|
||||
(
|
||||
const word& name,
|
||||
const label size
|
||||
);
|
||||
|
||||
//- Convert float data to VTK field
|
||||
template<class Type>
|
||||
vtkSmartPointer<vtkFloatArray> convertFieldToVTK
|
||||
(
|
||||
const word& name,
|
||||
const Field<Type>& fld
|
||||
);
|
||||
const UList<Type>& fld
|
||||
) const;
|
||||
|
||||
//- Face set/zone field
|
||||
template<class Type>
|
||||
@ -308,7 +473,7 @@ class vtkPVFoam
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld,
|
||||
const labelUList& faceLabels
|
||||
);
|
||||
) const;
|
||||
|
||||
//- Volume field
|
||||
template<class Type>
|
||||
@ -316,7 +481,7 @@ class vtkPVFoam
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld,
|
||||
const foamVtuData& vtuData
|
||||
);
|
||||
) const;
|
||||
|
||||
|
||||
//- Convert volume fields
|
||||
@ -392,9 +557,8 @@ class vtkPVFoam
|
||||
|
||||
//- Point field
|
||||
template<class Type>
|
||||
void convertPointField
|
||||
vtkSmartPointer<vtkFloatArray> convertPointField
|
||||
(
|
||||
vtkUnstructuredGrid* vtkmesh,
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& pfld,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& vfld,
|
||||
const foamVtuData& vtuData
|
||||
@ -403,17 +567,6 @@ class vtkPVFoam
|
||||
|
||||
// GUI selection helper functions
|
||||
|
||||
//- Only retain specified fields
|
||||
static void pruneObjectList
|
||||
(
|
||||
IOobjectList& objects,
|
||||
const hashedWordList& retain
|
||||
);
|
||||
|
||||
|
||||
//- Get the first word from selectedPartIds_
|
||||
word getPartName(const int partId) const;
|
||||
|
||||
//- Get the first word from the reader 'parts' selection
|
||||
word getReaderPartName(const int partId) const;
|
||||
|
||||
|
||||
@ -30,6 +30,7 @@ InClass
|
||||
#define vtkPVFoamFieldTemplates_C
|
||||
|
||||
// OpenFOAM includes
|
||||
#include "error.H"
|
||||
#include "emptyFvPatchField.H"
|
||||
#include "wallPolyPatch.H"
|
||||
#include "faceSet.H"
|
||||
@ -81,34 +82,51 @@ void Foam::vtkPVFoam::convertVolField
|
||||
convertVolFieldBlock(fld, ptfPtr, rangeCellZones_); // cellZones
|
||||
convertVolFieldBlock(fld, ptfPtr, rangeCellSets_); // cellSets
|
||||
|
||||
|
||||
// Patches - skip field conversion for groups
|
||||
// Patches - currently skip field conversion for groups
|
||||
for (auto partId : rangePatches_)
|
||||
{
|
||||
if
|
||||
if (!selectedPartIds_.found(partId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
foamVtpData& vtpData = iter.object();
|
||||
auto dataset = vtpData.dataset;
|
||||
|
||||
const labelList& patchIds = vtpData.additionalIds();
|
||||
if (patchIds.empty())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// This is slightly roundabout, but we deal with groups and with
|
||||
// single patches.
|
||||
// For groups (spanning several patches) it is fairly messy to
|
||||
// get interpolated point fields. We would need to create a indirect
|
||||
// patch each time to obtain the mesh points. We thus skip that.
|
||||
//
|
||||
// To improve code reuse, we allocate the CellData as a zeroed-field
|
||||
// ahead of time.
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> cdata = zeroVTKField<Type>
|
||||
(
|
||||
!selectedPartIds_.found(partId)
|
||||
|| selectedPartIds_[partId].startsWith("group/")
|
||||
)
|
||||
fld.name(),
|
||||
dataset->GetNumberOfPolys()
|
||||
);
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> pdata;
|
||||
const bool allowPdata = (interpField && patchIds.size() == 1);
|
||||
|
||||
label coffset = 0; // the write offset into cell-data
|
||||
for (label patchId : patchIds)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const word patchName = getPartName(partId);
|
||||
const label patchId = patches.findPatchID(patchName);
|
||||
|
||||
if (patchId < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto iter = cachedVtp_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
|
||||
const fvPatchField<Type>& ptf = fld.boundaryField()[patchId];
|
||||
|
||||
if
|
||||
@ -128,48 +146,42 @@ void Foam::vtkPVFoam::convertVolField
|
||||
fvPatchField<Type>(p, fld).patchInternalField()
|
||||
);
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> cdata =
|
||||
convertFieldToVTK
|
||||
(
|
||||
fld.name(),
|
||||
tpptf()
|
||||
);
|
||||
vtkmesh->GetCellData()->AddArray(cdata);
|
||||
coffset += transcribeFloatData(cdata, tpptf(), coffset);
|
||||
|
||||
if (patchId < patchInterpList.size())
|
||||
if (allowPdata && patchId < patchInterpList.size())
|
||||
{
|
||||
vtkSmartPointer<vtkFloatArray> pdata = convertFieldToVTK
|
||||
pdata = convertFieldToVTK
|
||||
(
|
||||
fld.name(),
|
||||
patchInterpList[patchId].faceToPointInterpolate(tpptf)()
|
||||
);
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vtkSmartPointer<vtkFloatArray> cdata =
|
||||
convertFieldToVTK
|
||||
(
|
||||
fld.name(),
|
||||
ptf
|
||||
);
|
||||
vtkmesh->GetCellData()->AddArray(cdata);
|
||||
coffset += transcribeFloatData(cdata, ptf, coffset);
|
||||
|
||||
if (patchId < patchInterpList.size())
|
||||
if (allowPdata && patchId < patchInterpList.size())
|
||||
{
|
||||
vtkSmartPointer<vtkFloatArray> pdata = convertFieldToVTK
|
||||
pdata = convertFieldToVTK
|
||||
(
|
||||
fld.name(),
|
||||
patchInterpList[patchId].faceToPointInterpolate(ptf)()
|
||||
);
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cdata)
|
||||
{
|
||||
dataset->GetCellData()->AddArray(cdata);
|
||||
}
|
||||
if (pdata)
|
||||
{
|
||||
dataset->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Face Zones
|
||||
for (auto partId : rangeFaceZones_)
|
||||
@ -178,15 +190,18 @@ void Foam::vtkPVFoam::convertVolField
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word zoneName = getFoamName(longName);
|
||||
|
||||
auto iter = cachedVtu_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
foamVtpData& vtpData = iter.object();
|
||||
auto dataset = vtpData.dataset;
|
||||
|
||||
const word zoneName = getPartName(partId);
|
||||
const faceZoneMesh& zMesh = mesh.faceZones();
|
||||
const label zoneId = zMesh.findZoneID(zoneName);
|
||||
|
||||
@ -195,15 +210,16 @@ void Foam::vtkPVFoam::convertVolField
|
||||
continue;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> cdata = convertFaceFieldToVTK
|
||||
vtkSmartPointer<vtkFloatArray> cdata =
|
||||
convertFaceFieldToVTK
|
||||
(
|
||||
fld,
|
||||
zMesh[zoneId]
|
||||
);
|
||||
|
||||
vtkmesh->GetCellData()->AddArray(cdata);
|
||||
dataset->GetCellData()->AddArray(cdata);
|
||||
|
||||
// TODO: points
|
||||
// TODO: point data
|
||||
}
|
||||
|
||||
|
||||
@ -214,26 +230,27 @@ void Foam::vtkPVFoam::convertVolField
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word selectName = getFoamName(longName);
|
||||
|
||||
auto iter = cachedVtu_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
|
||||
const word selectName = getPartName(partId);
|
||||
const faceSet fSet(mesh, selectName);
|
||||
foamVtpData& vtpData = iter.object();
|
||||
auto dataset = vtpData.dataset;
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> cdata = convertFaceFieldToVTK
|
||||
(
|
||||
fld,
|
||||
fSet.sortedToc()
|
||||
vtpData.cellMap()
|
||||
);
|
||||
|
||||
vtkmesh->GetCellData()->AddArray(cdata);
|
||||
dataset->GetCellData()->AddArray(cdata);
|
||||
|
||||
// TODO: points
|
||||
// TODO: point data
|
||||
}
|
||||
}
|
||||
|
||||
@ -246,29 +263,23 @@ void Foam::vtkPVFoam::convertVolFields
|
||||
const IOobjectList& objects
|
||||
)
|
||||
{
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> FieldType;
|
||||
|
||||
forAllConstIters(objects, iter)
|
||||
{
|
||||
// Restrict to GeometricField<Type, ...>
|
||||
if
|
||||
(
|
||||
iter()->headerClassName()
|
||||
!= GeometricField<Type, fvPatchField, volMesh>::typeName
|
||||
)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& ioobj = *(iter.object());
|
||||
|
||||
if (ioobj.headerClassName() == FieldType::typeName)
|
||||
{
|
||||
// Load field
|
||||
GeometricField<Type, fvPatchField, volMesh> fld
|
||||
(
|
||||
*iter(),
|
||||
mesh
|
||||
);
|
||||
FieldType fld(ioobj, mesh);
|
||||
|
||||
// Convert
|
||||
convertVolField(patchInterpList, fld);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
@ -279,22 +290,21 @@ void Foam::vtkPVFoam::convertDimFields
|
||||
const IOobjectList& objects
|
||||
)
|
||||
{
|
||||
typedef DimensionedField<Type, volMesh> FieldType;
|
||||
typedef GeometricField<Type, fvPatchField, volMesh> VolFieldType;
|
||||
|
||||
forAllConstIters(objects, iter)
|
||||
{
|
||||
// Restrict to DimensionedField<Type, ...>
|
||||
if
|
||||
(
|
||||
iter()->headerClassName()
|
||||
!= DimensionedField<Type, volMesh>::typeName
|
||||
)
|
||||
const auto& ioobj = *(iter.object());
|
||||
|
||||
if (ioobj.headerClassName() != FieldType::typeName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
// Load field
|
||||
DimensionedField<Type, volMesh> dimFld(*iter(), mesh);
|
||||
FieldType dimFld(ioobj, mesh);
|
||||
|
||||
// Construct volField with zero-gradient patch fields
|
||||
|
||||
@ -345,25 +355,33 @@ void Foam::vtkPVFoam::convertVolFieldBlock
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
|
||||
auto iter = cachedVtu_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
auto iter = cachedVtu_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtuData = (*iter);
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
foamVtuData& vtuData = iter.object();
|
||||
auto dataset = vtuData.dataset;
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> cdata = convertVolFieldToVTK
|
||||
(
|
||||
fld,
|
||||
vtuData
|
||||
);
|
||||
vtkmesh->GetCellData()->AddArray(cdata);
|
||||
dataset->GetCellData()->AddArray(cdata);
|
||||
|
||||
if (ptfPtr.valid())
|
||||
{
|
||||
convertPointField(vtkmesh, ptfPtr(), fld, vtuData);
|
||||
vtkSmartPointer<vtkFloatArray> pdata = convertPointField
|
||||
(
|
||||
ptfPtr(),
|
||||
fld,
|
||||
vtuData
|
||||
);
|
||||
dataset->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -382,17 +400,16 @@ void Foam::vtkPVFoam::convertPointFields
|
||||
)
|
||||
{
|
||||
const polyMesh& mesh = pMesh.mesh();
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
typedef GeometricField<Type, pointPatchField, pointMesh> FieldType;
|
||||
|
||||
forAllConstIters(objects, iter)
|
||||
{
|
||||
const word& fieldName = iter()->name();
|
||||
// Restrict to this GeometricField<Type, ...>
|
||||
if
|
||||
(
|
||||
iter()->headerClassName()
|
||||
!= GeometricField<Type, pointPatchField, pointMesh>::typeName
|
||||
)
|
||||
const auto& ioobj = *(iter.object());
|
||||
|
||||
const word& fieldName = ioobj.name();
|
||||
if (ioobj.headerClassName() != FieldType::typeName)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
@ -402,15 +419,13 @@ void Foam::vtkPVFoam::convertPointFields
|
||||
Info<< "convertPointFields : " << fieldName << endl;
|
||||
}
|
||||
|
||||
GeometricField<Type, pointPatchField, pointMesh> pfld(*iter(), pMesh);
|
||||
|
||||
FieldType pfld(ioobj, pMesh);
|
||||
|
||||
convertPointFieldBlock(pfld, rangeVolume_); // internalMesh
|
||||
convertPointFieldBlock(pfld, rangeCellZones_); // cellZones
|
||||
convertPointFieldBlock(pfld, rangeCellSets_); // cellSets
|
||||
|
||||
|
||||
// Patches)
|
||||
// Patches - currently skip field conversion for groups
|
||||
for (auto partId : rangePatches_)
|
||||
{
|
||||
if (!selectedPartIds_.found(partId))
|
||||
@ -419,26 +434,22 @@ void Foam::vtkPVFoam::convertPointFields
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
|
||||
if (longName.startsWith("group/"))
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Skip patch-groups
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
foamVtpData& vtpData = iter.object();
|
||||
auto dataset = vtpData.dataset;
|
||||
|
||||
const word patchName = getPartName(partId);
|
||||
const label patchId = patches.findPatchID(patchName);
|
||||
|
||||
if (patchId < 0)
|
||||
const labelList& patchIds = vtpData.additionalIds();
|
||||
if (patchIds.size() != 1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
auto iter = cachedVtp_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
const label patchId = patchIds[0];
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> pdata = convertFieldToVTK
|
||||
(
|
||||
@ -446,27 +457,28 @@ void Foam::vtkPVFoam::convertPointFields
|
||||
pfld.boundaryField()[patchId].patchInternalField()()
|
||||
);
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(pdata);
|
||||
dataset->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
|
||||
//
|
||||
// Convert (selected) faceZones
|
||||
//
|
||||
// Face Zones
|
||||
for (auto partId : rangeFaceZones_)
|
||||
{
|
||||
if (!selectedPartIds_.found(partId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word zoneName = getFoamName(longName);
|
||||
|
||||
auto iter = cachedVtp_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
foamVtpData& vtpData = iter.object();
|
||||
auto dataset = vtpData.dataset;
|
||||
|
||||
const word zoneName = getPartName(partId);
|
||||
const label zoneId = mesh.faceZones().findZoneID(zoneName);
|
||||
|
||||
if (zoneId < 0)
|
||||
@ -488,7 +500,7 @@ void Foam::vtkPVFoam::convertPointFields
|
||||
znfld
|
||||
);
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(pdata);
|
||||
dataset->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -507,63 +519,58 @@ void Foam::vtkPVFoam::convertPointFieldBlock
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
|
||||
auto iter = cachedVtu_.find(selectedPartIds_[partId]);
|
||||
if (!iter.found() || ! (*iter).vtkmesh)
|
||||
auto iter = cachedVtu_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtuData = (*iter);
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
foamVtuData& vtuData = iter.object();
|
||||
auto dataset = vtuData.dataset;
|
||||
|
||||
convertPointField
|
||||
vtkSmartPointer<vtkFloatArray> pdata = convertPointField
|
||||
(
|
||||
vtkmesh,
|
||||
pfld,
|
||||
GeometricField<Type, fvPatchField, volMesh>::null(),
|
||||
vtuData
|
||||
);
|
||||
|
||||
dataset->GetPointData()->AddArray(pdata);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
void Foam::vtkPVFoam::convertPointField
|
||||
vtkSmartPointer<vtkFloatArray> Foam::vtkPVFoam::convertPointField
|
||||
(
|
||||
vtkUnstructuredGrid* vtkmesh,
|
||||
const GeometricField<Type, pointPatchField, pointMesh>& pfld,
|
||||
const GeometricField<Type, fvPatchField, volMesh>& vfld,
|
||||
const foamVtuData& vtuData
|
||||
)
|
||||
{
|
||||
if (!vtkmesh)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
const label nComp = pTraits<Type>::nComponents;
|
||||
const int nComp(pTraits<Type>::nComponents);
|
||||
const labelUList& addPointCellLabels = vtuData.additionalIds();
|
||||
const labelUList& pointMap = vtuData.pointMap();
|
||||
|
||||
// Use a pointMap or address directly into mesh
|
||||
const label nPoints = (pointMap.size() ? pointMap.size() : pfld.size());
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> fldData =
|
||||
vtkSmartPointer<vtkFloatArray>::New();
|
||||
|
||||
fldData->SetNumberOfComponents(nComp);
|
||||
fldData->SetNumberOfTuples(nPoints + addPointCellLabels.size());
|
||||
auto data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
data->SetNumberOfComponents(nComp);
|
||||
data->SetNumberOfTuples(nPoints + addPointCellLabels.size());
|
||||
|
||||
// Note: using the name of the original volField
|
||||
// not the name generated by the interpolation "volPointInterpolate(<name>)"
|
||||
|
||||
if (&vfld != &GeometricField<Type, fvPatchField, volMesh>::null())
|
||||
if (notNull(vfld))
|
||||
{
|
||||
fldData->SetName(vfld.name().c_str());
|
||||
data->SetName(vfld.name().c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
fldData->SetName(pfld.name().c_str());
|
||||
data->SetName(pfld.name().c_str());
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -589,7 +596,7 @@ void Foam::vtkPVFoam::convertPointField
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
|
||||
fldData->SetTuple(pointi++, vec);
|
||||
data->SetTuple(pointi++, vec);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -603,13 +610,13 @@ void Foam::vtkPVFoam::convertPointField
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
|
||||
fldData->SetTuple(pointi++, vec);
|
||||
data->SetTuple(pointi++, vec);
|
||||
}
|
||||
}
|
||||
|
||||
// Continue additional points
|
||||
// Continue with additional points
|
||||
|
||||
if (&vfld != &GeometricField<Type, fvPatchField, volMesh>::null())
|
||||
if (notNull(vfld))
|
||||
{
|
||||
forAll(addPointCellLabels, apI)
|
||||
{
|
||||
@ -620,7 +627,7 @@ void Foam::vtkPVFoam::convertPointField
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
|
||||
fldData->SetTuple(pointi++, vec);
|
||||
data->SetTuple(pointi++, vec);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -634,11 +641,11 @@ void Foam::vtkPVFoam::convertPointField
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
|
||||
fldData->SetTuple(pointi++, vec);
|
||||
data->SetTuple(pointi++, vec);
|
||||
}
|
||||
}
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(fldData);
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -656,19 +663,23 @@ void Foam::vtkPVFoam::convertLagrangianFields
|
||||
{
|
||||
forAllConstIters(objects, iter)
|
||||
{
|
||||
// restrict to this IOField<Type>
|
||||
if (iter()->headerClassName() == IOField<Type>::typeName)
|
||||
{
|
||||
IOField<Type> fld(*iter());
|
||||
// Restrict to IOField<Type>
|
||||
const auto& ioobj = *(iter.object());
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> fldData =
|
||||
if (ioobj.headerClassName() == IOField<Type>::typeName)
|
||||
{
|
||||
IOField<Type> fld(ioobj);
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> data =
|
||||
convertFieldToVTK
|
||||
(
|
||||
fld.name(),
|
||||
ioobj.name(),
|
||||
fld
|
||||
);
|
||||
|
||||
vtkmesh->GetPointData()->AddArray(fldData);
|
||||
// Provide identical data as cell and as point data
|
||||
vtkmesh->GetCellData()->AddArray(data);
|
||||
vtkmesh->GetPointData()->AddArray(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -679,45 +690,116 @@ void Foam::vtkPVFoam::convertLagrangianFields
|
||||
// low-level conversions
|
||||
//
|
||||
|
||||
template<class Type>
|
||||
vtkSmartPointer<vtkFloatArray>
|
||||
Foam::vtkPVFoam::zeroVTKField
|
||||
(
|
||||
const word& name,
|
||||
const label size
|
||||
)
|
||||
{
|
||||
auto data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
|
||||
data->SetName(name.c_str());
|
||||
data->SetNumberOfComponents(int(pTraits<Type>::nComponents));
|
||||
data->SetNumberOfTuples(size);
|
||||
|
||||
data->Fill(0);
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
Foam::label Foam::vtkPVFoam::transcribeFloatData
|
||||
(
|
||||
vtkFloatArray* array,
|
||||
const UList<Type>& input,
|
||||
const label start
|
||||
)
|
||||
{
|
||||
const int nComp(pTraits<Type>::nComponents);
|
||||
|
||||
if (array->GetNumberOfComponents() != nComp)
|
||||
{
|
||||
FatalErrorInFunction
|
||||
<< "vtk array '" << array->GetName()
|
||||
<< "' has mismatch in number of components for type '"
|
||||
<< pTraits<Type>::typeName
|
||||
<< "' : target array has " << array->GetNumberOfComponents()
|
||||
<< " components instead of " << nComp
|
||||
<< endl;
|
||||
}
|
||||
|
||||
const vtkIdType maxSize = array->GetNumberOfTuples();
|
||||
const vtkIdType endPos = vtkIdType(start) + vtkIdType(input.size());
|
||||
|
||||
if (start < 0 || vtkIdType(start) >= maxSize)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "vtk array '" << array->GetName()
|
||||
<< "' copy with out-of-range (0-" << long(maxSize-1) << ")"
|
||||
<< " starting location"
|
||||
<< endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
else if (endPos > maxSize)
|
||||
{
|
||||
WarningInFunction
|
||||
<< "vtk array '" << array->GetName()
|
||||
<< "' copy ends out-of-range (" << long(maxSize) << ")"
|
||||
<< " using sizing (start,size) = ("
|
||||
<< start << "," << input.size() << ")"
|
||||
<< endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float scratch[nComp];
|
||||
forAll(input, idx)
|
||||
{
|
||||
const Type& t = input[idx];
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
{
|
||||
scratch[d] = component(t, d);
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(scratch);
|
||||
|
||||
array->SetTuple(start+idx, scratch);
|
||||
}
|
||||
|
||||
return input.size();
|
||||
}
|
||||
|
||||
|
||||
template<class Type>
|
||||
vtkSmartPointer<vtkFloatArray>
|
||||
Foam::vtkPVFoam::convertFieldToVTK
|
||||
(
|
||||
const word& name,
|
||||
const Field<Type>& fld
|
||||
)
|
||||
const UList<Type>& fld
|
||||
) const
|
||||
{
|
||||
const int nComp(pTraits<Type>::nComponents);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "convert Field<" << pTraits<Type>::typeName << "> "
|
||||
Info<< "convert UList<" << pTraits<Type>::typeName << "> "
|
||||
<< name
|
||||
<< " size=" << fld.size()
|
||||
<< " nComp=" << label(pTraits<Type>::nComponents) << endl;
|
||||
<< " nComp=" << nComp << endl;
|
||||
}
|
||||
|
||||
const label nComp = pTraits<Type>::nComponents;
|
||||
auto data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> fldData =
|
||||
vtkSmartPointer<vtkFloatArray>::New();
|
||||
data->SetName(name.c_str());
|
||||
data->SetNumberOfComponents(nComp);
|
||||
data->SetNumberOfTuples(fld.size());
|
||||
|
||||
fldData->SetNumberOfComponents(nComp);
|
||||
fldData->SetNumberOfTuples(fld.size());
|
||||
fldData->SetName(name.c_str());
|
||||
transcribeFloatData(data, fld);
|
||||
|
||||
float vec[nComp];
|
||||
forAll(fld, idx)
|
||||
{
|
||||
const Type& t = fld[idx];
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
{
|
||||
vec[d] = component(t, d);
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
|
||||
fldData->SetTuple(idx, vec);
|
||||
}
|
||||
|
||||
return fldData;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -727,34 +809,32 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld,
|
||||
const labelUList& faceLabels
|
||||
)
|
||||
) const
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "convert face field: "
|
||||
<< fld.name()
|
||||
<< " size=" << faceLabels.size()
|
||||
<< " nComp=" << label(pTraits<Type>::nComponents) << endl;
|
||||
<< " nComp=" << int(pTraits<Type>::nComponents) << endl;
|
||||
}
|
||||
|
||||
const fvMesh& mesh = fld.mesh();
|
||||
|
||||
const label nComp = pTraits<Type>::nComponents;
|
||||
const int nComp(pTraits<Type>::nComponents);
|
||||
const label nInternalFaces = mesh.nInternalFaces();
|
||||
const labelList& faceOwner = mesh.faceOwner();
|
||||
const labelList& faceNeigh = mesh.faceNeighbour();
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> fldData =
|
||||
vtkSmartPointer<vtkFloatArray>::New();
|
||||
auto data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
data->SetName(fld.name().c_str());
|
||||
data->SetNumberOfComponents(nComp);
|
||||
data->SetNumberOfTuples(faceLabels.size());
|
||||
|
||||
fldData->SetNumberOfComponents(nComp);
|
||||
fldData->SetNumberOfTuples(faceLabels.size());
|
||||
fldData->SetName(fld.name().c_str());
|
||||
float scratch[nComp];
|
||||
|
||||
float vec[nComp];
|
||||
|
||||
// for interior faces: average owner/neighbour
|
||||
// for boundary faces: owner
|
||||
// Interior faces: average owner/neighbour
|
||||
// Boundary faces: the owner value
|
||||
forAll(faceLabels, idx)
|
||||
{
|
||||
const label faceNo = faceLabels[idx];
|
||||
@ -764,7 +844,7 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
|
||||
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
{
|
||||
vec[d] = component(t, d);
|
||||
scratch[d] = component(t, d);
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -772,15 +852,15 @@ Foam::vtkPVFoam::convertFaceFieldToVTK
|
||||
const Type& t = fld[faceOwner[faceNo]];
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
{
|
||||
vec[d] = component(t, d);
|
||||
scratch[d] = component(t, d);
|
||||
}
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
foamPvFields::remapTuple<Type>(scratch);
|
||||
|
||||
fldData->SetTuple(idx, vec);
|
||||
data->SetTuple(idx, scratch);
|
||||
}
|
||||
|
||||
return fldData;
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
@ -790,17 +870,15 @@ Foam::vtkPVFoam::convertVolFieldToVTK
|
||||
(
|
||||
const GeometricField<Type, fvPatchField, volMesh>& fld,
|
||||
const foamVtuData& vtuData
|
||||
)
|
||||
) const
|
||||
{
|
||||
const label nComp = pTraits<Type>::nComponents;
|
||||
const labelList& cellMap = vtuData.cellMap();
|
||||
const int nComp(pTraits<Type>::nComponents);
|
||||
const labelUList& cellMap = vtuData.cellMap();
|
||||
|
||||
vtkSmartPointer<vtkFloatArray> fldData =
|
||||
vtkSmartPointer<vtkFloatArray>::New();
|
||||
|
||||
fldData->SetNumberOfComponents(nComp);
|
||||
fldData->SetNumberOfTuples(cellMap.size());
|
||||
fldData->SetName(fld.name().c_str());
|
||||
auto data = vtkSmartPointer<vtkFloatArray>::New();
|
||||
data->SetName(fld.name().c_str());
|
||||
data->SetNumberOfComponents(nComp);
|
||||
data->SetNumberOfTuples(cellMap.size());
|
||||
|
||||
if (debug)
|
||||
{
|
||||
@ -812,20 +890,20 @@ Foam::vtkPVFoam::convertVolFieldToVTK
|
||||
<< ") nComp=" << nComp << endl;
|
||||
}
|
||||
|
||||
float vec[nComp];
|
||||
float scratch[nComp];
|
||||
forAll(cellMap, idx)
|
||||
{
|
||||
const Type& t = fld[cellMap[idx]];
|
||||
for (direction d=0; d<nComp; ++d)
|
||||
{
|
||||
vec[d] = component(t, d);
|
||||
scratch[d] = component(t, d);
|
||||
}
|
||||
foamPvFields::remapTuple<Type>(vec);
|
||||
foamPvFields::remapTuple<Type>(scratch);
|
||||
|
||||
fldData->SetTuple(idx, vec);
|
||||
data->SetTuple(idx, scratch);
|
||||
}
|
||||
|
||||
return fldData;
|
||||
return data;
|
||||
}
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
@ -40,28 +40,6 @@ License
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
void Foam::vtkPVFoam::pruneObjectList
|
||||
(
|
||||
IOobjectList& objects,
|
||||
const hashedWordList& retain
|
||||
)
|
||||
{
|
||||
if (retain.empty())
|
||||
{
|
||||
objects.clear();
|
||||
}
|
||||
|
||||
// only retain specified fields
|
||||
forAllIters(objects, iter)
|
||||
{
|
||||
if (!retain.found(iter()->name()))
|
||||
{
|
||||
objects.erase(iter);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtkPVFoam::convertVolFields()
|
||||
{
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
@ -80,7 +58,7 @@ void Foam::vtkPVFoam::convertVolFields()
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
objects.filterKeys(selectedFields);
|
||||
|
||||
if (objects.empty())
|
||||
{
|
||||
@ -89,7 +67,7 @@ void Foam::vtkPVFoam::convertVolFields()
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> convert volume fields" << endl;
|
||||
Info<< "<beg> " << FUNCTION_NAME << endl;
|
||||
forAllConstIters(objects, iter)
|
||||
{
|
||||
Info<< " " << iter()->name()
|
||||
@ -132,7 +110,7 @@ void Foam::vtkPVFoam::convertVolFields()
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<end> convert volume fields" << endl;
|
||||
Info<< "<end> " << FUNCTION_NAME << endl;
|
||||
printMemory();
|
||||
}
|
||||
}
|
||||
@ -159,7 +137,7 @@ void Foam::vtkPVFoam::convertPointFields()
|
||||
// Get objects (fields) for this time - only keep selected fields
|
||||
// the region name is already in the mesh db
|
||||
IOobjectList objects(mesh, dbPtr_().timeName());
|
||||
pruneObjectList(objects, selectedFields);
|
||||
objects.filterKeys(selectedFields);
|
||||
|
||||
if (objects.empty())
|
||||
{
|
||||
@ -196,7 +174,7 @@ void Foam::vtkPVFoam::convertPointFields()
|
||||
|
||||
void Foam::vtkPVFoam::convertLagrangianFields()
|
||||
{
|
||||
arrayRange& range = rangeLagrangian_;
|
||||
const arrayRange& range = rangeLagrangian_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
hashedWordList selectedFields = getSelected
|
||||
@ -211,7 +189,7 @@ void Foam::vtkPVFoam::convertLagrangianFields()
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> convert Lagrangian fields" << endl;
|
||||
Info<< "<beg> " << FUNCTION_NAME << endl;
|
||||
printMemory();
|
||||
}
|
||||
|
||||
@ -222,14 +200,16 @@ void Foam::vtkPVFoam::convertLagrangianFields()
|
||||
continue;
|
||||
}
|
||||
|
||||
const word cloudName = getPartName(partId);
|
||||
auto iter = cachedVtp_.find(selectedPartIds_[partId]);
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word cloudName = getFoamName(longName);
|
||||
|
||||
if (!iter.found() || !(*iter).vtkmesh)
|
||||
auto iter = cachedVtp_.find(longName);
|
||||
if (!iter.found() || !iter.object().dataset)
|
||||
{
|
||||
// Should not happen, but for safety require a vtk geometry
|
||||
continue;
|
||||
}
|
||||
auto vtkmesh = (*iter).vtkmesh;
|
||||
auto dataset = iter.object().dataset;
|
||||
|
||||
// Get the Lagrangian fields for this time and this cloud
|
||||
// but only keep selected fields
|
||||
@ -240,7 +220,7 @@ void Foam::vtkPVFoam::convertLagrangianFields()
|
||||
dbPtr_().timeName(),
|
||||
cloud::prefix/cloudName
|
||||
);
|
||||
pruneObjectList(objects, selectedFields);
|
||||
objects.filterKeys(selectedFields);
|
||||
|
||||
if (objects.empty())
|
||||
{
|
||||
@ -257,17 +237,17 @@ void Foam::vtkPVFoam::convertLagrangianFields()
|
||||
}
|
||||
}
|
||||
|
||||
convertLagrangianFields<label>(objects, vtkmesh);
|
||||
convertLagrangianFields<scalar>(objects, vtkmesh);
|
||||
convertLagrangianFields<vector>(objects, vtkmesh);
|
||||
convertLagrangianFields<sphericalTensor>(objects, vtkmesh);
|
||||
convertLagrangianFields<symmTensor>(objects, vtkmesh);
|
||||
convertLagrangianFields<tensor>(objects, vtkmesh);
|
||||
convertLagrangianFields<label>(objects, dataset);
|
||||
convertLagrangianFields<scalar>(objects, dataset);
|
||||
convertLagrangianFields<vector>(objects, dataset);
|
||||
convertLagrangianFields<sphericalTensor>(objects, dataset);
|
||||
convertLagrangianFields<symmTensor>(objects, dataset);
|
||||
convertLagrangianFields<tensor>(objects, dataset);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<end> convert Lagrangian fields" << endl;
|
||||
Info<< "<end> " << FUNCTION_NAME << endl;
|
||||
printMemory();
|
||||
}
|
||||
}
|
||||
|
||||
@ -44,7 +44,7 @@ License
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshVolume()
|
||||
{
|
||||
arrayRange& range = rangeVolume_;
|
||||
const arrayRange& range = rangeVolume_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
@ -60,15 +60,38 @@ void Foam::vtkPVFoam::convertMeshVolume()
|
||||
if (selectedPartIds_.found(partId))
|
||||
{
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
foamVtuData& vtuData = cachedVtu_(longName);
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh =
|
||||
volumeVTKMesh
|
||||
(
|
||||
mesh,
|
||||
cachedVtu_(longName)
|
||||
);
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkgeom;
|
||||
if (vtuData.nPoints())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "reuse " << longName << nl;
|
||||
}
|
||||
vtuData.reuse(); // reuse
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "move points " << longName << nl;
|
||||
}
|
||||
vtkgeom = vtuData.getCopy();
|
||||
vtkgeom->SetPoints(movePoints(mesh, vtuData));
|
||||
}
|
||||
}
|
||||
|
||||
cachedVtu_[longName].vtkmesh = vtkmesh;
|
||||
if (!vtkgeom)
|
||||
{
|
||||
// Nothing usable from cache - create new geometry
|
||||
vtkgeom = volumeVTKMesh(mesh, vtuData);
|
||||
}
|
||||
|
||||
vtuData.set(vtkgeom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -82,7 +105,7 @@ void Foam::vtkPVFoam::convertMeshVolume()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshLagrangian()
|
||||
{
|
||||
arrayRange& range = rangeLagrangian_;
|
||||
const arrayRange& range = rangeLagrangian_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
@ -96,16 +119,13 @@ void Foam::vtkPVFoam::convertMeshLagrangian()
|
||||
if (selectedPartIds_.found(partId))
|
||||
{
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word cloudName = getPartName(partId);
|
||||
const word cloudName = getFoamName(longName);
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
lagrangianVTKMesh
|
||||
// Direct conversion, no caching for Lagrangian
|
||||
cachedVtp_(longName).set
|
||||
(
|
||||
mesh,
|
||||
cloudName
|
||||
lagrangianVTKMesh(mesh, cloudName)
|
||||
);
|
||||
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
}
|
||||
}
|
||||
|
||||
@ -119,7 +139,7 @@ void Foam::vtkPVFoam::convertMeshLagrangian()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshPatches()
|
||||
{
|
||||
arrayRange& range = rangePatches_;
|
||||
const arrayRange& range = rangePatches_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
const polyBoundaryMesh& patches = mesh.boundaryMesh();
|
||||
|
||||
@ -136,14 +156,42 @@ void Foam::vtkPVFoam::convertMeshPatches()
|
||||
continue;
|
||||
}
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word partName = getPartName(partId);
|
||||
const word partName = getFoamName(longName);
|
||||
foamVtpData& vtpData = cachedVtp_(longName);
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh;
|
||||
vtkSmartPointer<vtkPolyData> vtkgeom;
|
||||
if (vtpData.nPoints())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
// Without movement is easy.
|
||||
if (debug)
|
||||
{
|
||||
Info<< "reuse " << longName << nl;
|
||||
}
|
||||
vtpData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
// Point movement on single patch is OK
|
||||
|
||||
const labelList& patchIds = vtpData.additionalIds();
|
||||
if (patchIds.size() == 1)
|
||||
{
|
||||
vtkgeom = vtpData.getCopy();
|
||||
vtkgeom->SetPoints(movePatchPoints(patches[patchIds[0]]));
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (longName.startsWith("group/"))
|
||||
{
|
||||
// Patch group. Collect patch faces.
|
||||
|
||||
vtpData.clear(); // Remove any old mappings
|
||||
|
||||
const labelList& patchIds =
|
||||
patches.groupPatchIDs().lookup(partName, labelList());
|
||||
|
||||
@ -153,19 +201,32 @@ void Foam::vtkPVFoam::convertMeshPatches()
|
||||
<< longName << endl;
|
||||
}
|
||||
|
||||
// Store good patch ids as additionalIds
|
||||
vtpData.additionalIds().reserve(patchIds.size());
|
||||
|
||||
label sz = 0;
|
||||
for (auto id : patchIds)
|
||||
{
|
||||
sz += patches[id].size();
|
||||
const label n = patches[id].size();
|
||||
|
||||
if (n)
|
||||
{
|
||||
vtpData.additionalIds().append(id);
|
||||
sz += n;
|
||||
}
|
||||
labelList faceLabels(sz);
|
||||
sz = 0;
|
||||
for (auto id : patchIds)
|
||||
}
|
||||
Foam::sort(vtpData.additionalIds());
|
||||
|
||||
// Temporarily (mis)use cellMap for face labels
|
||||
DynamicList<label>& faceLabels = vtpData.cellMap();
|
||||
faceLabels.reserve(sz);
|
||||
|
||||
for (auto id : vtpData.additionalIds())
|
||||
{
|
||||
const auto& pp = patches[id];
|
||||
forAll(pp, i)
|
||||
{
|
||||
faceLabels[sz++] = pp.start()+i;
|
||||
faceLabels.append(pp.start()+i);
|
||||
}
|
||||
}
|
||||
|
||||
@ -177,11 +238,15 @@ void Foam::vtkPVFoam::convertMeshPatches()
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
vtkmesh = patchVTKMesh(partName, pp);
|
||||
vtkgeom = patchVTKMesh(pp);
|
||||
}
|
||||
|
||||
faceLabels.clear(); // Unneeded
|
||||
}
|
||||
else
|
||||
{
|
||||
vtpData.clear(); // Remove any old mappings
|
||||
|
||||
const label patchId = patches.findPatchID(partName);
|
||||
|
||||
if (debug)
|
||||
@ -192,13 +257,20 @@ void Foam::vtkPVFoam::convertMeshPatches()
|
||||
|
||||
if (patchId >= 0)
|
||||
{
|
||||
vtkmesh = patchVTKMesh(partName, patches[patchId]);
|
||||
// Store good patch id as additionalIds
|
||||
vtpData.additionalIds() = {patchId};
|
||||
|
||||
vtkgeom = patchVTKMesh(patches[patchId]);
|
||||
}
|
||||
}
|
||||
|
||||
if (vtkmesh)
|
||||
if (vtkgeom)
|
||||
{
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
vtpData.set(vtkgeom);
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedVtp_.erase(longName);
|
||||
}
|
||||
}
|
||||
|
||||
@ -210,36 +282,6 @@ void Foam::vtkPVFoam::convertMeshPatches()
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshSubset
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
const string& longName
|
||||
)
|
||||
{
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh = volumeVTKMesh
|
||||
(
|
||||
subsetter.subMesh(),
|
||||
cachedVtu_(longName)
|
||||
);
|
||||
|
||||
// Convert cellMap, addPointCellLabels to global cell ids
|
||||
inplaceRenumber
|
||||
(
|
||||
subsetter.cellMap(),
|
||||
cachedVtu_[longName].cellMap()
|
||||
);
|
||||
inplaceRenumber
|
||||
(
|
||||
subsetter.cellMap(),
|
||||
cachedVtu_[longName].additionalIds()
|
||||
);
|
||||
|
||||
// copy pointMap as well, otherwise pointFields fail
|
||||
cachedVtu_[longName].pointMap() = subsetter.pointMap();
|
||||
cachedVtu_[longName].vtkmesh = vtkmesh;
|
||||
}
|
||||
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshCellZones()
|
||||
{
|
||||
const arrayRange& range = rangeCellZones_;
|
||||
@ -265,7 +307,7 @@ void Foam::vtkPVFoam::convertMeshCellZones()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word zoneName = getPartName(partId);
|
||||
const word zoneName = getFoamName(longName);
|
||||
const label zoneId = zMesh.findZoneID(zoneName);
|
||||
|
||||
if (zoneId < 0)
|
||||
@ -279,10 +321,43 @@ void Foam::vtkPVFoam::convertMeshCellZones()
|
||||
<< zoneName << endl;
|
||||
}
|
||||
|
||||
foamVtuData& vtuData = cachedVtu_(longName);
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkgeom;
|
||||
if (vtuData.nPoints() && vtuData.pointMap().size())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "reuse " << longName << nl;
|
||||
}
|
||||
vtuData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "move points " << longName << nl;
|
||||
}
|
||||
vtkgeom = vtuData.getCopy();
|
||||
vtkgeom->SetPoints
|
||||
(
|
||||
movePoints(mesh, vtuData, vtuData.pointMap())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vtkgeom)
|
||||
{
|
||||
fvMeshSubset subsetter(mesh);
|
||||
subsetter.setLargeCellSubset(zMesh[zoneId]);
|
||||
|
||||
convertMeshSubset(subsetter, longName);
|
||||
vtkgeom = volumeVTKSubsetMesh(subsetter, vtuData);
|
||||
}
|
||||
|
||||
vtuData.set(vtkgeom);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -312,18 +387,50 @@ void Foam::vtkPVFoam::convertMeshCellSets()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word partName = getPartName(partId);
|
||||
const word partName = getFoamName(longName);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating VTK mesh for cellSet=" << partName << endl;
|
||||
}
|
||||
|
||||
const cellSet cSet(mesh, partName);
|
||||
fvMeshSubset subsetter(mesh);
|
||||
subsetter.setLargeCellSubset(cSet);
|
||||
foamVtuData& vtuData = cachedVtu_(longName);
|
||||
|
||||
convertMeshSubset(subsetter, longName);
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkgeom;
|
||||
if (vtuData.nPoints() && vtuData.pointMap().size())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "reuse " << longName << nl;
|
||||
}
|
||||
vtuData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "move points " << longName << nl;
|
||||
}
|
||||
vtkgeom = vtuData.getCopy();
|
||||
vtkgeom->SetPoints
|
||||
(
|
||||
movePoints(mesh, vtuData, vtuData.pointMap())
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (!vtkgeom)
|
||||
{
|
||||
fvMeshSubset subsetter(mesh);
|
||||
subsetter.setLargeCellSubset(cellSet(mesh, partName));
|
||||
|
||||
vtkgeom = volumeVTKSubsetMesh(subsetter, vtuData);
|
||||
}
|
||||
|
||||
vtuData.set(vtkgeom);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -336,7 +443,7 @@ void Foam::vtkPVFoam::convertMeshCellSets()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshFaceZones()
|
||||
{
|
||||
arrayRange& range = rangeFaceZones_;
|
||||
const arrayRange& range = rangeFaceZones_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (range.empty())
|
||||
@ -359,28 +466,49 @@ void Foam::vtkPVFoam::convertMeshFaceZones()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word zoneName = getPartName(partId);
|
||||
const word zoneName = getFoamName(longName);
|
||||
const label zoneId = zMesh.findZoneID(zoneName);
|
||||
|
||||
if (zoneId < 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating VTKmesh for faceZone[" << zoneId << "] "
|
||||
<< zoneName << endl;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
patchVTKMesh
|
||||
(
|
||||
zoneName,
|
||||
zMesh[zoneId]()
|
||||
);
|
||||
foamVtpData& vtpData = cachedVtp_(longName);
|
||||
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
vtkSmartPointer<vtkPolyData> vtkgeom;
|
||||
if (vtpData.nPoints())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
// Without movement is easy.
|
||||
if (debug)
|
||||
{
|
||||
Info<<"reuse " << longName << nl;
|
||||
}
|
||||
vtpData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
// Need point maps etc - not worth it at the moment
|
||||
}
|
||||
}
|
||||
|
||||
if (!vtkgeom)
|
||||
{
|
||||
vtpData.clear(); // No additional ids, maps
|
||||
|
||||
const primitiveFacePatch& pp = zMesh[zoneId]();
|
||||
vtkgeom = patchVTKMesh(pp);
|
||||
}
|
||||
|
||||
vtpData.set(vtkgeom);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -393,7 +521,7 @@ void Foam::vtkPVFoam::convertMeshFaceZones()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshFaceSets()
|
||||
{
|
||||
arrayRange& range = rangeFaceSets_;
|
||||
const arrayRange& range = rangeFaceSets_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
@ -410,35 +538,61 @@ void Foam::vtkPVFoam::convertMeshFaceSets()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word partName = getPartName(partId);
|
||||
const word partName = getFoamName(longName);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating VTK mesh for faceSet=" << partName << endl;
|
||||
}
|
||||
|
||||
// faces in sorted order for more reliability
|
||||
const labelList faceLabels = faceSet(mesh, partName).sortedToc();
|
||||
foamVtpData& vtpData = cachedVtp_(longName);
|
||||
|
||||
uindirectPrimitivePatch p
|
||||
vtkSmartPointer<vtkPolyData> vtkgeom;
|
||||
if (vtpData.nPoints())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
// Without movement is easy.
|
||||
if (debug)
|
||||
{
|
||||
Info<<"reuse " << longName << nl;
|
||||
}
|
||||
vtpData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
// Need point maps etc - not worth it at the moment
|
||||
}
|
||||
}
|
||||
|
||||
if (!vtkgeom)
|
||||
{
|
||||
vtpData.clear(); // No other additional ids, maps
|
||||
|
||||
// Misuse cellMap for face labels - sorted order for reliability
|
||||
vtpData.cellMap() = faceSet(mesh, partName).sortedToc();
|
||||
|
||||
if (vtpData.cellMap().size())
|
||||
{
|
||||
uindirectPrimitivePatch pp
|
||||
(
|
||||
UIndirectList<face>(mesh.faces(), faceLabels),
|
||||
UIndirectList<face>(mesh.faces(), vtpData.cellMap()),
|
||||
mesh.points()
|
||||
);
|
||||
|
||||
if (p.empty())
|
||||
{
|
||||
continue;
|
||||
vtkgeom = patchVTKMesh(pp);
|
||||
}
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
patchVTKMesh
|
||||
(
|
||||
"faceSet:" + partName,
|
||||
p
|
||||
);
|
||||
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
if (vtkgeom)
|
||||
{
|
||||
vtpData.set(vtkgeom);
|
||||
}
|
||||
else
|
||||
{
|
||||
cachedVtp_.erase(longName);
|
||||
}
|
||||
}
|
||||
|
||||
if (debug)
|
||||
@ -451,7 +605,7 @@ void Foam::vtkPVFoam::convertMeshFaceSets()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshPointZones()
|
||||
{
|
||||
arrayRange& range = rangePointZones_;
|
||||
const arrayRange& range = rangePointZones_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
@ -471,7 +625,7 @@ void Foam::vtkPVFoam::convertMeshPointZones()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word zoneName = getPartName(partId);
|
||||
const word zoneName = getFoamName(longName);
|
||||
const label zoneId = zMesh.findZoneID(zoneName);
|
||||
|
||||
if (zoneId < 0)
|
||||
@ -479,29 +633,50 @@ void Foam::vtkPVFoam::convertMeshPointZones()
|
||||
continue;
|
||||
}
|
||||
|
||||
const pointField& meshPoints = mesh.points();
|
||||
const labelUList& pointLabels = zMesh[zoneId];
|
||||
foamVtpData& vtpData = cachedVtp_(longName);
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(pointLabels.size());
|
||||
|
||||
forAll(pointLabels, pointi)
|
||||
vtkSmartPointer<vtkPolyData> vtkgeom;
|
||||
if (vtpData.nPoints() && vtpData.pointMap().size())
|
||||
{
|
||||
vtkpoints->SetPoint
|
||||
(
|
||||
pointi,
|
||||
meshPoints[pointLabels[pointi]].v_
|
||||
);
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "reusing " << longName << nl;
|
||||
}
|
||||
vtpData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "move points " << longName << nl;
|
||||
}
|
||||
vtkgeom = vtpData.getCopy();
|
||||
}
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
vtkSmartPointer<vtkPolyData>::New();
|
||||
if (!vtkgeom)
|
||||
{
|
||||
// First time, or topo change
|
||||
vtkgeom = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtpData.pointMap() = zMesh[zoneId];
|
||||
}
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
const pointField& points = mesh.points();
|
||||
const labelUList& pointMap = vtpData.pointMap();
|
||||
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(pointMap.size());
|
||||
forAll(pointMap, pointi)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_);
|
||||
}
|
||||
|
||||
vtkgeom->SetPoints(vtkpoints);
|
||||
vtpData.set(vtkgeom);
|
||||
}
|
||||
}
|
||||
|
||||
@ -515,7 +690,7 @@ void Foam::vtkPVFoam::convertMeshPointZones()
|
||||
|
||||
void Foam::vtkPVFoam::convertMeshPointSets()
|
||||
{
|
||||
arrayRange& range = rangePointSets_;
|
||||
const arrayRange& range = rangePointSets_;
|
||||
const fvMesh& mesh = *meshPtr_;
|
||||
|
||||
if (debug)
|
||||
@ -532,36 +707,52 @@ void Foam::vtkPVFoam::convertMeshPointSets()
|
||||
}
|
||||
|
||||
const auto& longName = selectedPartIds_[partId];
|
||||
const word partName = getPartName(partId);
|
||||
const word partName = getFoamName(longName);
|
||||
|
||||
foamVtpData& vtpData = cachedVtp_(longName);
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkgeom;
|
||||
if (vtpData.nPoints() && vtpData.pointMap().size())
|
||||
{
|
||||
if (meshState_ == polyMesh::UNCHANGED)
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "Creating VTK mesh for pointSet=" << partName << endl;
|
||||
Info<< "reusing " << longName << nl;
|
||||
}
|
||||
|
||||
const pointField& meshPoints = mesh.points();
|
||||
const labelList pointLabels = pointSet(mesh, partName).sortedToc();
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(pointLabels.size());
|
||||
|
||||
forAll(pointLabels, pointi)
|
||||
vtpData.reuse();
|
||||
continue;
|
||||
}
|
||||
else if (meshState_ == polyMesh::POINTS_MOVED)
|
||||
{
|
||||
vtkpoints->SetPoint
|
||||
(
|
||||
pointi,
|
||||
meshPoints[pointLabels[pointi]].v_
|
||||
);
|
||||
if (debug)
|
||||
{
|
||||
Info<< "move points " << longName << nl;
|
||||
}
|
||||
vtkgeom = vtpData.getCopy();
|
||||
}
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
vtkSmartPointer<vtkPolyData>::New();
|
||||
if (!vtkgeom)
|
||||
{
|
||||
// First time, or topo change
|
||||
vtkgeom = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtpData.pointMap() = pointSet(mesh, partName).sortedToc();
|
||||
}
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
const pointField& points = mesh.points();
|
||||
const labelUList& pointMap = vtpData.pointMap();
|
||||
|
||||
cachedVtp_(longName).vtkmesh = vtkmesh;
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(pointMap.size());
|
||||
forAll(pointMap, pointi)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi, points[pointMap[pointi]].v_);
|
||||
}
|
||||
|
||||
vtkgeom->SetPoints(vtkpoints);
|
||||
vtpData.set(vtkgeom);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
|
||||
@ -43,7 +43,7 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
|
||||
(
|
||||
const polyMesh& mesh,
|
||||
const word& cloudName
|
||||
)
|
||||
) const
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh;
|
||||
|
||||
@ -73,29 +73,19 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::lagrangianVTKMesh
|
||||
Info<< "cloud with " << parcels.size() << " parcels" << endl;
|
||||
}
|
||||
|
||||
vtkmesh = vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkSmartPointer<vtkCellArray> vtkcells =
|
||||
vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkpoints->SetNumberOfPoints(parcels.size());
|
||||
vtkcells->Allocate(2*parcels.size());
|
||||
// If reusing memory, ensure insert always starts from 0
|
||||
vtkcells->Reset();
|
||||
|
||||
vtkIdType particleId = 0;
|
||||
forAllConstIters(parcels, iter)
|
||||
{
|
||||
vtkpoints->SetPoint(particleId, iter().position().v_);
|
||||
vtkcells->InsertNextCell(1, &particleId); // VTK_VERTEX
|
||||
particleId++;
|
||||
++particleId;
|
||||
}
|
||||
|
||||
vtkmesh = vtkSmartPointer<vtkPolyData>::New();
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
vtkmesh->SetVerts(vtkcells);
|
||||
vtkmesh->SetVerts(foamPvCore::identityVertices(parcels.size()));
|
||||
}
|
||||
|
||||
if (debug)
|
||||
|
||||
@ -28,18 +28,89 @@ License
|
||||
|
||||
// OpenFOAM includes
|
||||
#include "fvMesh.H"
|
||||
#include "fvMeshSubset.H"
|
||||
#include "foamVtkAdaptors.H"
|
||||
#include "foamVtuSizing.H"
|
||||
|
||||
// VTK includes
|
||||
#include "vtkUnstructuredGrid.h"
|
||||
#include "foamVtkAdaptors.H"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
|
||||
vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePoints
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtuData& vtuData
|
||||
)
|
||||
{
|
||||
// Convert OpenFOAM mesh vertices to VTK
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
// Normal points
|
||||
const pointField& points = mesh.points();
|
||||
|
||||
// Additional cell centres
|
||||
const labelList& addPoints = vtuData.additionalIds();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(points.size() + addPoints.size());
|
||||
|
||||
// Normal points
|
||||
label pointi = 0;
|
||||
forAll(points, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, points[i].v_);
|
||||
}
|
||||
|
||||
// Cell centres
|
||||
forAll(addPoints, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_);
|
||||
}
|
||||
|
||||
return vtkpoints;
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePoints
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
const foamVtuData& vtuData,
|
||||
const labelUList& pointMap
|
||||
)
|
||||
{
|
||||
// Convert OpenFOAM mesh vertices to VTK
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
// Normal points
|
||||
const pointField& points = mesh.points();
|
||||
|
||||
// Additional cell centres
|
||||
const labelList& addPoints = vtuData.additionalIds();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(pointMap.size() + addPoints.size());
|
||||
|
||||
// Normal points
|
||||
label pointi = 0;
|
||||
forAll(pointMap, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, points[pointMap[i]].v_);
|
||||
}
|
||||
|
||||
// Cell centres
|
||||
forAll(addPoints, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_);
|
||||
}
|
||||
|
||||
return vtkpoints;
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
foamVtuData& vtuData
|
||||
foamVtuData& vtuData,
|
||||
const bool decompPoly
|
||||
)
|
||||
{
|
||||
if (debug)
|
||||
@ -48,25 +119,15 @@ vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
|
||||
printMemory();
|
||||
}
|
||||
|
||||
foamVtuSizing sizing(mesh, !reader_->GetUseVTKPolyhedron());
|
||||
foamVtuSizing sizing(mesh, decompPoly);
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh =
|
||||
vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
auto cellTypes = vtkSmartPointer<vtkUnsignedCharArray>::New();
|
||||
|
||||
auto cellTypes =
|
||||
nonNullSmartPointer<vtkUnsignedCharArray>(vtkmesh->GetCellTypesArray());
|
||||
auto cells = vtkSmartPointer<vtkCellArray>::New();
|
||||
auto faces = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
auto cells =
|
||||
nonNullSmartPointer<vtkCellArray>(vtkmesh->GetCells());
|
||||
|
||||
auto faces =
|
||||
nonNullSmartPointer<vtkIdTypeArray>(vtkmesh->GetFaces());
|
||||
|
||||
auto cellLocations =
|
||||
nonNullSmartPointer<vtkIdTypeArray>(vtkmesh->GetCellLocationsArray());
|
||||
|
||||
auto faceLocations =
|
||||
nonNullSmartPointer<vtkIdTypeArray>(vtkmesh->GetFaceLocations());
|
||||
auto cellLocations = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
auto faceLocations = vtkSmartPointer<vtkIdTypeArray>::New();
|
||||
|
||||
UList<uint8_t> cellTypesUL =
|
||||
vtkUList
|
||||
@ -116,33 +177,12 @@ vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
|
||||
static_cast<foamVtkMeshMaps&>(vtuData)
|
||||
);
|
||||
|
||||
auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
|
||||
// Convert OpenFOAM mesh vertices to VTK
|
||||
// - can only do this *after* populating the decompInfo with cell-ids
|
||||
// for any additional points (ie, mesh cell-centres)
|
||||
vtkSmartPointer<vtkPoints> vtkpoints = vtkmesh->GetPoints();
|
||||
if (!vtkpoints)
|
||||
{
|
||||
// No points previously, add an entry
|
||||
vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
}
|
||||
|
||||
vtkpoints->SetNumberOfPoints(sizing.nFieldPoints());
|
||||
|
||||
// Normal points
|
||||
const pointField& points = mesh.points();
|
||||
const labelList& addPoints = vtuData.additionalIds();
|
||||
|
||||
label pointi = 0;
|
||||
forAll(points, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, points[i].v_);
|
||||
}
|
||||
forAll(addPoints, i)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi++, mesh.C()[addPoints[i]].v_);
|
||||
}
|
||||
vtkmesh->SetPoints(movePoints(mesh, vtuData));
|
||||
|
||||
if (facesUL.size())
|
||||
{
|
||||
@ -177,4 +217,48 @@ vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKSubsetMesh
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
foamVtuData& vtuData,
|
||||
const bool decompPoly
|
||||
)
|
||||
{
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh = volumeVTKMesh
|
||||
(
|
||||
subsetter.subMesh(),
|
||||
vtuData,
|
||||
decompPoly
|
||||
);
|
||||
|
||||
// Convert cellMap, addPointCellLabels to global cell ids
|
||||
vtuData.renumberCells(subsetter.cellMap());
|
||||
|
||||
// Copy pointMap as well, otherwise pointFields fail
|
||||
vtuData.pointMap() = subsetter.pointMap();
|
||||
|
||||
return vtkmesh;
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKMesh
|
||||
(
|
||||
const fvMesh& mesh,
|
||||
foamVtuData& vtuData
|
||||
) const
|
||||
{
|
||||
return volumeVTKMesh(mesh, vtuData, this->decomposePoly_);
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> Foam::vtkPVFoam::volumeVTKSubsetMesh
|
||||
(
|
||||
const fvMeshSubset& subsetter,
|
||||
foamVtuData& vtuData
|
||||
) const
|
||||
{
|
||||
return volumeVTKSubsetMesh(subsetter, vtuData, this->decomposePoly_);
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -28,6 +28,7 @@ License
|
||||
// OpenFOAM includes
|
||||
#include "polyPatch.H"
|
||||
#include "primitivePatch.H"
|
||||
#include "foamVtkAdaptors.H"
|
||||
|
||||
// VTK includes
|
||||
#include "vtkCellArray.h"
|
||||
@ -35,38 +36,36 @@ License
|
||||
#include "vtkPolyData.h"
|
||||
#include "vtkSmartPointer.h"
|
||||
|
||||
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
template<class PatchType>
|
||||
vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::patchVTKMesh
|
||||
vtkSmartPointer<vtkPoints> Foam::vtkPVFoam::movePatchPoints
|
||||
(
|
||||
const string& name,
|
||||
const PatchType& p
|
||||
)
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> patchVTKMesh - " << name << endl;
|
||||
printMemory();
|
||||
}
|
||||
|
||||
// Convert OpenFOAM mesh vertices to VTK
|
||||
const Foam::pointField& points = p.localPoints();
|
||||
const pointField& points = p.localPoints();
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkpoints->SetNumberOfPoints(points.size());
|
||||
forAll(points, i)
|
||||
{
|
||||
vtkpoints->SetPoint(i, points[i].v_);
|
||||
}
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
|
||||
// Add faces as polygons
|
||||
return vtkpoints;
|
||||
}
|
||||
|
||||
|
||||
template<class PatchType>
|
||||
vtkSmartPointer<vtkCellArray> Foam::vtkPVFoam::patchFacesVTKCells
|
||||
(
|
||||
const PatchType& p
|
||||
)
|
||||
{
|
||||
// Faces as polygons
|
||||
const faceList& faces = p.localFaces();
|
||||
|
||||
label nAlloc = faces.size();
|
||||
@ -75,32 +74,45 @@ vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::patchVTKMesh
|
||||
nAlloc += faces[facei].size();
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkCellArray> vtkcells =
|
||||
vtkSmartPointer<vtkCellArray>::New();
|
||||
auto cells = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
vtkcells->Allocate(nAlloc);
|
||||
// If reusing memory, ensure insert always starts from 0
|
||||
vtkcells->Reset();
|
||||
UList<vtkIdType> cellsUL =
|
||||
vtkUList
|
||||
(
|
||||
cells,
|
||||
faces.size(),
|
||||
nAlloc
|
||||
);
|
||||
|
||||
// Cell connectivity for polygons
|
||||
// [size, verts..., size, verts... ]
|
||||
label idx = 0;
|
||||
forAll(faces, facei)
|
||||
{
|
||||
const face& f = faces[facei];
|
||||
vtkIdType nodeIds[f.size()];
|
||||
|
||||
cellsUL[idx++] = f.size();
|
||||
|
||||
forAll(f, fp)
|
||||
{
|
||||
nodeIds[fp] = f[fp];
|
||||
cellsUL[idx++] = f[fp];
|
||||
}
|
||||
vtkcells->InsertNextCell(f.size(), nodeIds);
|
||||
}
|
||||
|
||||
vtkmesh->SetPolys(vtkcells);
|
||||
return cells;
|
||||
}
|
||||
|
||||
if (debug)
|
||||
|
||||
template<class PatchType>
|
||||
vtkSmartPointer<vtkPolyData> Foam::vtkPVFoam::patchVTKMesh
|
||||
(
|
||||
const PatchType& p
|
||||
)
|
||||
{
|
||||
Info<< "<end> patchVTKMesh - " << name << endl;
|
||||
printMemory();
|
||||
}
|
||||
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
vtkmesh->SetPoints(movePatchPoints(p));
|
||||
vtkmesh->SetPolys(patchFacesVTKCells(p));
|
||||
|
||||
return vtkmesh;
|
||||
}
|
||||
|
||||
@ -163,7 +163,7 @@ void Foam::vtkPVFoam::updateInfoLagrangian
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> updateInfoLagrangian" << nl
|
||||
Info<< "<beg> " << FUNCTION_NAME << nl
|
||||
<< " " << dbPtr_->timePath()/cloud::prefix << endl;
|
||||
}
|
||||
|
||||
@ -194,7 +194,7 @@ void Foam::vtkPVFoam::updateInfoLagrangian
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<end> updateInfoLagrangian" << endl;
|
||||
Info<< "<end> " << FUNCTION_NAME << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -207,7 +207,7 @@ void Foam::vtkPVFoam::updateInfoPatches
|
||||
{
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> updateInfoPatches"
|
||||
Info<< "<beg> " << FUNCTION_NAME
|
||||
<< " [meshPtr=" << (meshPtr_ ? "set" : "null") << "]" << endl;
|
||||
}
|
||||
|
||||
@ -409,7 +409,7 @@ void Foam::vtkPVFoam::updateInfoPatches
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<end> updateInfoPatches" << endl;
|
||||
Info<< "<end> " << FUNCTION_NAME << endl;
|
||||
}
|
||||
}
|
||||
|
||||
@ -591,7 +591,7 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
|
||||
}
|
||||
|
||||
// Preserve the enabled selections
|
||||
HashSet<string> enabledEntries = getSelectedArrayEntries(select);
|
||||
HashSet<string> enabled = getSelectedArraySet(select);
|
||||
select->RemoveAllArrays();
|
||||
|
||||
// TODO - currently only get fields from ONE cloud
|
||||
@ -631,25 +631,7 @@ void Foam::vtkPVFoam::updateInfoLagrangianFields
|
||||
addToSelection<IOField<tensor>>(select, objects);
|
||||
|
||||
// Restore the enabled selections
|
||||
setSelectedArrayEntries(select, enabledEntries);
|
||||
|
||||
if (debug > 1)
|
||||
{
|
||||
boolList status;
|
||||
const label nElem = getSelected(status, select);
|
||||
|
||||
forAll(status, i)
|
||||
{
|
||||
Info<< " lagrangian[" << i << "] = "
|
||||
<< status[i]
|
||||
<< " : " << select->GetArrayName(i) << nl;
|
||||
}
|
||||
|
||||
if (!nElem)
|
||||
{
|
||||
Info<< " lagrangian[none]" << nl;
|
||||
}
|
||||
}
|
||||
setSelectedArrayEntries(select, enabled);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
|
||||
@ -45,16 +45,16 @@ void Foam::vtkPVFoam::updateInfoFields
|
||||
<< endl;
|
||||
}
|
||||
|
||||
HashSet<string> enabledEntries;
|
||||
HashSet<string> enabled;
|
||||
if (!select->GetNumberOfArrays() && !meshPtr_)
|
||||
{
|
||||
// enable 'p' and 'U' only on the first call
|
||||
enabledEntries = { "p", "U" };
|
||||
// Enable 'p' and 'U' only on the first call
|
||||
enabled = { "p", "U" };
|
||||
}
|
||||
else
|
||||
{
|
||||
// preserve the enabled selections
|
||||
enabledEntries = getSelectedArrayEntries(select);
|
||||
// Preserve the enabled selections
|
||||
enabled = getSelectedArraySet(select);
|
||||
}
|
||||
|
||||
select->RemoveAllArrays();
|
||||
@ -127,7 +127,7 @@ void Foam::vtkPVFoam::updateInfoFields
|
||||
|
||||
|
||||
// Restore the enabled selections
|
||||
setSelectedArrayEntries(select, enabledEntries);
|
||||
setSelectedArrayEntries(select, enabled);
|
||||
|
||||
if (debug)
|
||||
{
|
||||
|
||||
@ -40,6 +40,7 @@ License
|
||||
// * * * * * * * * * * * * * Static Member Functions * * * * * * * * * * * * //
|
||||
|
||||
// file-scope
|
||||
// Widget properties
|
||||
static QWidget* setWidgetProperties
|
||||
(
|
||||
QWidget* widget,
|
||||
@ -67,6 +68,7 @@ static QWidget* setWidgetProperties
|
||||
|
||||
|
||||
// file-scope
|
||||
// Button properties
|
||||
static QAbstractButton* setButtonProperties
|
||||
(
|
||||
QAbstractButton* b,
|
||||
|
||||
@ -60,8 +60,7 @@ namespace Foam
|
||||
const Foam::point& pt
|
||||
)
|
||||
{
|
||||
vtkSmartPointer<vtkTextActor> txt =
|
||||
vtkSmartPointer<vtkTextActor>::New();
|
||||
auto txt = vtkSmartPointer<vtkTextActor>::New();
|
||||
|
||||
txt->SetInput(s.c_str());
|
||||
|
||||
@ -310,8 +309,8 @@ void Foam::vtkPVblockMesh::updateInfo()
|
||||
HashSet<string> enabledEdges;
|
||||
if (!firstTime)
|
||||
{
|
||||
enabledParts = getSelectedArrayEntries(blockSelection);
|
||||
enabledEdges = getSelectedArrayEntries(edgeSelection);
|
||||
enabledParts = getSelectedArraySet(blockSelection);
|
||||
enabledEdges = getSelectedArraySet(edgeSelection);
|
||||
}
|
||||
|
||||
// Clear current mesh parts list
|
||||
@ -407,14 +406,6 @@ void Foam::vtkPVblockMesh::Update
|
||||
{
|
||||
reader_->UpdateProgress(0.1);
|
||||
|
||||
// Set up mesh parts selection(s)
|
||||
getSelected(blockStatus_, reader_->GetBlockSelection());
|
||||
|
||||
// Set up curved edges selection(s)
|
||||
getSelected(edgeStatus_, reader_->GetCurvedEdgesSelection());
|
||||
|
||||
reader_->UpdateProgress(0.2);
|
||||
|
||||
// Update the OpenFOAM mesh
|
||||
updateFoamMesh();
|
||||
reader_->UpdateProgress(0.5);
|
||||
@ -427,7 +418,6 @@ void Foam::vtkPVblockMesh::Update
|
||||
convertMeshEdges(output, blockNo);
|
||||
|
||||
reader_->UpdateProgress(0.8);
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -25,13 +25,18 @@ Class
|
||||
Foam::vtkPVblockMesh
|
||||
|
||||
Description
|
||||
Provides a reader interface for OpenFOAM blockMesh to VTK interaction
|
||||
The backend for the vtkPVblockMeshReader reader module -
|
||||
providing a paraview reader interface for OpenFOAM blockMesh.
|
||||
|
||||
The block reader module can assist when creating a blockMeshDict
|
||||
for use with the blockMesh utility. As well as blocks, it can be
|
||||
used to visualize edges,corners and patch names.
|
||||
|
||||
There is no native VTK equivalent for this functionality.
|
||||
|
||||
SourceFiles
|
||||
vtkPVblockMesh.C
|
||||
vtkPVblockMeshConvert.C
|
||||
vtkPVblockMeshUpdate.C
|
||||
vtkPVblockMeshUtils.C
|
||||
|
||||
// Needed by VTK:
|
||||
vtkDataArrayTemplateImplicit.txx
|
||||
@ -95,12 +100,6 @@ class vtkPVblockMesh
|
||||
//- The mesh directory for the region
|
||||
fileName meshDir_;
|
||||
|
||||
//- Selected geometrical parts
|
||||
boolList blockStatus_;
|
||||
|
||||
//- Selected curved edges
|
||||
boolList edgeStatus_;
|
||||
|
||||
//- First instance and size of bleckMesh blocks
|
||||
// used to index into blockStatus_
|
||||
arrayRange rangeBlocks_;
|
||||
|
||||
@ -53,7 +53,11 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
|
||||
Info<< "<beg> convertMeshBlocks" << endl;
|
||||
}
|
||||
|
||||
vtkDataArraySelection* selection = reader_->GetBlockSelection();
|
||||
const Map<string> blockStatus = getSelectedArrayMap
|
||||
(
|
||||
reader_->GetBlockSelection()
|
||||
);
|
||||
|
||||
arrayRange& range = rangeBlocks_;
|
||||
range.block(blockNo); // set output block
|
||||
label datasetNo = 0; // restart at dataset 0
|
||||
@ -61,29 +65,23 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
|
||||
const blockMesh& blkMesh = *meshPtr_;
|
||||
const pointField blkPoints(blkMesh.vertices() * blkMesh.scaleFactor());
|
||||
|
||||
int blockI = 0;
|
||||
for
|
||||
(
|
||||
auto iter = range.cbegin();
|
||||
iter != range.cend();
|
||||
++iter, ++blockI
|
||||
)
|
||||
vtkIdType nodeIds[8]; // Space for VTK_HEXAHEDRON vertices
|
||||
int blockId = -1;
|
||||
for (auto partId : range)
|
||||
{
|
||||
const auto partId = *iter;
|
||||
if (!blockStatus_[partId])
|
||||
++blockId; // Increment first
|
||||
if (!blockStatus.found(partId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = blockStatus[partId];
|
||||
|
||||
const blockDescriptor& blockDef = blkMesh[blockI];
|
||||
const blockDescriptor& blockDef = blkMesh[blockId];
|
||||
const labelList& blockLabels = blockDef.blockShape();
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkpoints->SetNumberOfPoints(blockLabels.size());
|
||||
|
||||
vtkIdType nodeIds[8];
|
||||
forAll(blockLabels, pointi)
|
||||
{
|
||||
vtkpoints->SetPoint
|
||||
@ -94,8 +92,7 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
|
||||
nodeIds[pointi] = pointi;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkUnstructuredGrid> vtkmesh =
|
||||
vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
auto vtkmesh = vtkSmartPointer<vtkUnstructuredGrid>::New();
|
||||
|
||||
vtkmesh->Allocate(1);
|
||||
vtkmesh->InsertNextCell
|
||||
@ -107,11 +104,7 @@ void Foam::vtkPVblockMesh::convertMeshBlocks
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
|
||||
addToBlock
|
||||
(
|
||||
output, vtkmesh, range, datasetNo,
|
||||
selection->GetArrayName(partId)
|
||||
);
|
||||
addToBlock(output, vtkmesh, range, datasetNo, longName);
|
||||
++datasetNo;
|
||||
}
|
||||
|
||||
@ -135,7 +128,11 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
int& blockNo
|
||||
)
|
||||
{
|
||||
vtkDataArraySelection* selection = reader_->GetCurvedEdgesSelection();
|
||||
const Map<string> edgeStatus = getSelectedArrayMap
|
||||
(
|
||||
reader_->GetCurvedEdgesSelection()
|
||||
);
|
||||
|
||||
arrayRange& range = rangeEdges_;
|
||||
|
||||
range.block(blockNo); // set output block
|
||||
@ -145,24 +142,20 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
const blockEdgeList& edges = blkMesh.edges();
|
||||
const scalar scaleFactor = blkMesh.scaleFactor();
|
||||
|
||||
int edgeI = 0;
|
||||
for
|
||||
(
|
||||
auto iter = range.cbegin();
|
||||
iter != range.cend();
|
||||
++iter, ++edgeI
|
||||
)
|
||||
int edgeId = -1;
|
||||
for (auto partId : range)
|
||||
{
|
||||
const auto partId = *iter;
|
||||
if (!edgeStatus_[partId])
|
||||
++edgeId; // Increment first
|
||||
if (!edgeStatus.found(partId))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
const auto& longName = edgeStatus[partId];
|
||||
|
||||
// search each block
|
||||
forAll(blkMesh, blockI)
|
||||
// Search each block
|
||||
forAll(blkMesh, blockId)
|
||||
{
|
||||
const blockDescriptor& blockDef = blkMesh[blockI];
|
||||
const blockDescriptor& blockDef = blkMesh[blockId];
|
||||
|
||||
edgeList blkEdges = blockDef.blockShape().edges();
|
||||
|
||||
@ -175,7 +168,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
label foundEdgeI = -1;
|
||||
forAll(blkEdges, blkEdgeI)
|
||||
{
|
||||
if (edges[edgeI].compare(blkEdges[blkEdgeI]))
|
||||
if (edges[edgeId].compare(blkEdges[blkEdgeI]))
|
||||
{
|
||||
foundEdgeI = blkEdgeI;
|
||||
break;
|
||||
@ -186,9 +179,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
{
|
||||
const List<point>& edgePoints = edgesPoints[foundEdgeI];
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkpoints->SetNumberOfPoints(edgePoints.size());
|
||||
|
||||
vtkIdType pointIds[edgePoints.size()];
|
||||
@ -200,8 +191,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
pointIds[pointi] = pointi;
|
||||
}
|
||||
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
vtkSmartPointer<vtkPolyData>::New();
|
||||
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
vtkmesh->Allocate(1);
|
||||
vtkmesh->InsertNextCell
|
||||
@ -213,11 +203,7 @@ void Foam::vtkPVblockMesh::convertMeshEdges
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
|
||||
addToBlock
|
||||
(
|
||||
output, vtkmesh, range, datasetNo,
|
||||
selection->GetArrayName(partId)
|
||||
);
|
||||
addToBlock(output, vtkmesh, range, datasetNo, longName);
|
||||
++datasetNo;
|
||||
|
||||
break;
|
||||
@ -253,35 +239,23 @@ void Foam::vtkPVblockMesh::convertMeshCorners
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<beg> convertMeshCorners" << endl;
|
||||
Info<< "<beg> " << FUNCTION_NAME << endl;
|
||||
}
|
||||
|
||||
if (true) // or some flag or other condition
|
||||
if (true) // Or some flag or other condition
|
||||
{
|
||||
vtkSmartPointer<vtkPolyData> vtkmesh =
|
||||
vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
vtkSmartPointer<vtkPoints> vtkpoints =
|
||||
vtkSmartPointer<vtkPoints>::New();
|
||||
|
||||
vtkSmartPointer<vtkCellArray> vtkcells =
|
||||
vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
auto vtkpoints = vtkSmartPointer<vtkPoints>::New();
|
||||
vtkpoints->SetNumberOfPoints(blkPoints.size());
|
||||
vtkcells->Allocate(2*blkPoints.size());
|
||||
// If reusing memory, ensure insert always starts from 0
|
||||
vtkcells->Reset();
|
||||
|
||||
vtkIdType pointId = 0;
|
||||
forAll(blkPoints, pointi)
|
||||
{
|
||||
vtkpoints->SetPoint(pointi, blkPoints[pointi].v_);
|
||||
vtkcells->InsertNextCell(1, &pointId); // VTK_VERTEX
|
||||
pointId++;
|
||||
}
|
||||
|
||||
auto vtkmesh = vtkSmartPointer<vtkPolyData>::New();
|
||||
|
||||
vtkmesh->SetPoints(vtkpoints);
|
||||
vtkmesh->SetVerts(vtkcells);
|
||||
vtkmesh->SetVerts(foamPvCore::identityVertices(blkPoints.size()));
|
||||
|
||||
addToBlock(output, vtkmesh, range, datasetNo, range.name());
|
||||
++datasetNo;
|
||||
@ -295,7 +269,7 @@ void Foam::vtkPVblockMesh::convertMeshCorners
|
||||
|
||||
if (debug)
|
||||
{
|
||||
Info<< "<end> convertMeshCorners" << endl;
|
||||
Info<< "<end> " << FUNCTION_NAME << endl;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -34,6 +34,8 @@ License
|
||||
#include "vtkInformation.h"
|
||||
#include "vtkSmartPointer.h"
|
||||
|
||||
#include "foamVtkAdaptors.H"
|
||||
|
||||
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
|
||||
|
||||
namespace Foam
|
||||
@ -82,7 +84,7 @@ void Foam::foamPvCore::addToBlock
|
||||
|
||||
block->SetBlock(datasetNo, dataset);
|
||||
|
||||
// name the output block when assigning dataset 0
|
||||
// Name the output block when assigning dataset 0
|
||||
if (datasetNo == 0)
|
||||
{
|
||||
output->GetMetaData(blockNo)->Set
|
||||
@ -103,34 +105,6 @@ void Foam::foamPvCore::addToBlock
|
||||
}
|
||||
|
||||
|
||||
int Foam::foamPvCore::getSelected
|
||||
(
|
||||
boolList& status,
|
||||
vtkDataArraySelection* selection
|
||||
)
|
||||
{
|
||||
const int n = selection->GetNumberOfArrays();
|
||||
if (status.size() != n)
|
||||
{
|
||||
status.setSize(n);
|
||||
status = false;
|
||||
}
|
||||
|
||||
int count = 0;
|
||||
forAll(status, i)
|
||||
{
|
||||
const bool setting = selection->GetArraySetting(i);
|
||||
if (setting)
|
||||
{
|
||||
++count;
|
||||
}
|
||||
status[i] = setting;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
|
||||
Foam::hashedWordList Foam::foamPvCore::getSelected
|
||||
(
|
||||
vtkDataArraySelection* select
|
||||
@ -173,54 +147,15 @@ Foam::hashedWordList Foam::foamPvCore::getSelected
|
||||
|
||||
|
||||
Foam::HashSet<Foam::string>
|
||||
Foam::foamPvCore::getSelectedArrayEntries
|
||||
Foam::foamPvCore::getSelectedArraySet
|
||||
(
|
||||
vtkDataArraySelection* select
|
||||
)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
HashSet<string> selections(2*n);
|
||||
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
if (select->GetArraySetting(i))
|
||||
{
|
||||
selections.insert(select->GetArrayName(i));
|
||||
}
|
||||
}
|
||||
|
||||
if (debug > 1)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
Info<< "available(";
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
Info<< " \"" << select->GetArrayName(i) << "\"";
|
||||
}
|
||||
Info<< " )\nselected(";
|
||||
|
||||
for (auto k : selections)
|
||||
{
|
||||
Info<< " " << k;
|
||||
}
|
||||
Info<< " )\n";
|
||||
}
|
||||
|
||||
return selections;
|
||||
}
|
||||
|
||||
|
||||
Foam::HashSet<Foam::string>
|
||||
Foam::foamPvCore::getSelectedArrayEntries
|
||||
(
|
||||
vtkDataArraySelection* select,
|
||||
const arrayRange& slice
|
||||
)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
HashSet<string> enabled(2*n);
|
||||
|
||||
for (auto i : slice)
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
if (select->GetArraySetting(i))
|
||||
{
|
||||
@ -230,8 +165,9 @@ Foam::foamPvCore::getSelectedArrayEntries
|
||||
|
||||
if (debug > 1)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
Info<< "available(";
|
||||
for (auto i : slice)
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
Info<< " \"" << select->GetArrayName(i) << "\"";
|
||||
}
|
||||
@ -248,25 +184,24 @@ Foam::foamPvCore::getSelectedArrayEntries
|
||||
}
|
||||
|
||||
|
||||
void Foam::foamPvCore::setSelectedArrayEntries
|
||||
Foam::Map<Foam::string>
|
||||
Foam::foamPvCore::getSelectedArrayMap
|
||||
(
|
||||
vtkDataArraySelection* select,
|
||||
const HashSet<string>& enabled
|
||||
vtkDataArraySelection* select
|
||||
)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
// disable everything not explicitly enabled
|
||||
select->DisableAllArrays();
|
||||
Map<string> enabled(2*n);
|
||||
|
||||
// Loop through entries, enabling as required
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
const char* arrayName = select->GetArrayName(i);
|
||||
if (enabled.found(arrayName))
|
||||
if (select->GetArraySetting(i))
|
||||
{
|
||||
select->EnableArray(arrayName);
|
||||
enabled.insert(i, select->GetArrayName(i));
|
||||
}
|
||||
}
|
||||
|
||||
return enabled;
|
||||
}
|
||||
|
||||
|
||||
@ -312,4 +247,29 @@ void Foam::foamPvCore::printMemory()
|
||||
}
|
||||
|
||||
|
||||
vtkSmartPointer<vtkCellArray> Foam::foamPvCore::identityVertices
|
||||
(
|
||||
const label size
|
||||
)
|
||||
{
|
||||
// VTK_VERTEX
|
||||
auto cells = vtkSmartPointer<vtkCellArray>::New();
|
||||
|
||||
UList<vtkIdType> cellsUL = vtkUList(cells, size, 2*size);
|
||||
|
||||
// Cell connectivity for vertex
|
||||
// [size, ids.., size, ids...]
|
||||
// which means
|
||||
// [1, id, 1, id, ...]
|
||||
label idx = 0;
|
||||
for (label id=0; id < size; ++id)
|
||||
{
|
||||
cellsUL[idx++] = 1;
|
||||
cellsUL[idx++] = id;
|
||||
}
|
||||
|
||||
return cells;
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
@ -40,17 +40,19 @@ SourceFiles
|
||||
#include "wordList.H"
|
||||
#include "Hash.H"
|
||||
#include "HashSet.H"
|
||||
#include "Map.H"
|
||||
#include "hashedWordList.H"
|
||||
#include "labelRange.H"
|
||||
|
||||
#include "vtkPoints.h"
|
||||
|
||||
// * * * * * * * * * * * * * Forward Declarations * * * * * * * * * * * * * //
|
||||
|
||||
class vtkCellArray;
|
||||
class vtkDataArraySelection;
|
||||
class vtkDataSet;
|
||||
class vtkMultiBlockDataSet;
|
||||
class vtkIndent;
|
||||
class vtkMultiBlockDataSet;
|
||||
class vtkPoints;
|
||||
template<class T> class vtkSmartPointer;
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
@ -168,13 +170,6 @@ public:
|
||||
);
|
||||
|
||||
|
||||
//- Retrieve the current selections into a boolList
|
||||
static int getSelected
|
||||
(
|
||||
boolList& lst,
|
||||
vtkDataArraySelection* select
|
||||
);
|
||||
|
||||
//- Retrieve the current selections as a hashedWordList,
|
||||
// while stripping off any prefix or suffix
|
||||
static hashedWordList getSelected
|
||||
@ -192,25 +187,24 @@ public:
|
||||
);
|
||||
|
||||
|
||||
//- Retrieve the currently enabled selections
|
||||
static HashSet<string> getSelectedArrayEntries
|
||||
//- Retrieve the currently enabled selections as hashset
|
||||
static HashSet<string> getSelectedArraySet
|
||||
(
|
||||
vtkDataArraySelection* select
|
||||
);
|
||||
|
||||
//- Retrieve a sub-list of the currently enabled selections
|
||||
static HashSet<string> getSelectedArrayEntries
|
||||
//- Retrieve the currently enabled selections as id/name map
|
||||
static Map<string> getSelectedArrayMap
|
||||
(
|
||||
vtkDataArraySelection* select,
|
||||
const arrayRange& slice
|
||||
vtkDataArraySelection* select
|
||||
);
|
||||
|
||||
|
||||
//- Enable the selection(s)
|
||||
template<class AnyValue, class AnyHasher>
|
||||
static void setSelectedArrayEntries
|
||||
(
|
||||
vtkDataArraySelection* select,
|
||||
const HashSet<string>& enabled
|
||||
const HashTable<AnyValue, string, AnyHasher>& enabled
|
||||
);
|
||||
|
||||
|
||||
@ -222,6 +216,13 @@ public:
|
||||
static void printMemory();
|
||||
|
||||
|
||||
//- Return an identity list of VTK_VERTEX
|
||||
static vtkSmartPointer<vtkCellArray> identityVertices
|
||||
(
|
||||
const label size
|
||||
);
|
||||
|
||||
|
||||
// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
|
||||
|
||||
}; // End class foamPvCore
|
||||
|
||||
@ -54,4 +54,27 @@ Foam::label Foam::foamPvCore::addToSelection
|
||||
}
|
||||
|
||||
|
||||
template<class AnyValue, class AnyHasher>
|
||||
void Foam::foamPvCore::setSelectedArrayEntries
|
||||
(
|
||||
vtkDataArraySelection* select,
|
||||
const HashTable<AnyValue, string, AnyHasher>& enabled
|
||||
)
|
||||
{
|
||||
const int n = select->GetNumberOfArrays();
|
||||
// disable everything not explicitly enabled
|
||||
select->DisableAllArrays();
|
||||
|
||||
// Loop through entries, enabling as required
|
||||
for (int i=0; i < n; ++i)
|
||||
{
|
||||
const char* arrayName = select->GetArrayName(i);
|
||||
if (enabled.found(arrayName))
|
||||
{
|
||||
select->EnableArray(arrayName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ************************************************************************* //
|
||||
|
||||
Reference in New Issue
Block a user