/*---------------------------------------------------------------------------*\
========= |
\\ / F ield | OpenFOAM: The Open Source CFD Toolbox
\\ / O peration |
\\ / A nd | Copyright (C) 2011-2015 OpenFOAM Foundation
\\/ M anipulation |
-------------------------------------------------------------------------------
License
This file is part of OpenFOAM.
OpenFOAM is free software: you can redistribute it and/or modify it
under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
OpenFOAM is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
You should have received a copy of the GNU General Public License
along with OpenFOAM. If not, see .
\*---------------------------------------------------------------------------*/
#include "vtkPV3blockMesh.H"
#include "vtkPV3blockMeshReader.h"
// OpenFOAM includes
#include "blockMesh.H"
#include "Time.H"
#include "patchZones.H"
#include "OStringStream.H"
// VTK includes
#include "vtkDataArraySelection.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkRenderer.h"
#include "vtkTextActor.h"
#include "vtkTextProperty.h"
// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
namespace Foam
{
defineTypeNameAndDebug(vtkPV3blockMesh, 0);
}
// * * * * * * * * * * * * * Private Member Functions * * * * * * * * * * * //
void Foam::vtkPV3blockMesh::resetCounters()
{
// Reset mesh part ids and sizes
arrayRangeBlocks_.reset();
arrayRangeEdges_.reset();
arrayRangeCorners_.reset();
}
void Foam::vtkPV3blockMesh::updateInfoBlocks
(
vtkDataArraySelection* arraySelection
)
{
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateInfoBlocks"
<< " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
}
arrayRangeBlocks_.reset( arraySelection->GetNumberOfArrays() );
const blockMesh& blkMesh = *meshPtr_;
const int nBlocks = blkMesh.size();
for (int blockI = 0; blockI < nBlocks; ++blockI)
{
const blockDescriptor& blockDef = blkMesh[blockI].blockDef();
word partName = Foam::name(blockI);
// append the (optional) zone name
if (!blockDef.zoneName().empty())
{
partName += " - " + blockDef.zoneName();
}
// Add blockId and zoneName to GUI list
arraySelection->AddArray(partName.c_str());
}
arrayRangeBlocks_ += nBlocks;
if (debug)
{
// just for debug info
getSelectedArrayEntries(arraySelection);
Info<< " Foam::vtkPV3blockMesh::updateInfoBlocks" << endl;
}
}
void Foam::vtkPV3blockMesh::updateInfoEdges
(
vtkDataArraySelection* arraySelection
)
{
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateInfoEdges"
<< " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "]" << endl;
}
arrayRangeEdges_.reset( arraySelection->GetNumberOfArrays() );
const blockMesh& blkMesh = *meshPtr_;
const curvedEdgeList& edges = blkMesh.edges();
const int nEdges = edges.size();
forAll(edges, edgeI)
{
OStringStream ostr;
ostr<< edges[edgeI].start() << ":" << edges[edgeI].end() << " - "
<< edges[edgeI].type();
// Add "beg:end - type" to GUI list
arraySelection->AddArray(ostr.str().c_str());
}
arrayRangeEdges_ += nEdges;
if (debug)
{
// just for debug info
getSelectedArrayEntries(arraySelection);
Info<< " Foam::vtkPV3blockMesh::updateInfoEdges" << endl;
}
}
// * * * * * * * * * * * * * * * * Constructors * * * * * * * * * * * * * * //
Foam::vtkPV3blockMesh::vtkPV3blockMesh
(
const char* const FileName,
vtkPV3blockMeshReader* reader
)
:
reader_(reader),
dbPtr_(NULL),
meshPtr_(NULL),
meshRegion_(polyMesh::defaultRegion),
meshDir_(polyMesh::meshSubDir),
arrayRangeBlocks_("block"),
arrayRangeEdges_("edges"),
arrayRangeCorners_("corners")
{
if (debug)
{
Info<< "Foam::vtkPV3blockMesh::vtkPV3blockMesh - "
<< FileName << endl;
}
// avoid argList and get rootPath/caseName directly from the file
fileName fullCasePath(fileName(FileName).path());
if (!isDir(fullCasePath))
{
return;
}
if (fullCasePath == ".")
{
fullCasePath = cwd();
}
// Set the case as an environment variable - some BCs might use this
if (fullCasePath.name().find("processor", 0) == 0)
{
const fileName globalCase = fullCasePath.path();
setEnv("FOAM_CASE", globalCase, true);
setEnv("FOAM_CASENAME", globalCase.name(), true);
}
else
{
setEnv("FOAM_CASE", fullCasePath, true);
setEnv("FOAM_CASENAME", fullCasePath.name(), true);
}
// look for 'case{region}.OpenFOAM'
// could be stringent and insist the prefix match the directory name...
// Note: cannot use fileName::name() due to the embedded '{}'
string caseName(fileName(FileName).lessExt());
string::size_type beg = caseName.find_last_of("/{");
string::size_type end = caseName.find('}', beg);
if
(
beg != string::npos && caseName[beg] == '{'
&& end != string::npos && end == caseName.size()-1
)
{
meshRegion_ = caseName.substr(beg+1, end-beg-1);
// some safety
if (meshRegion_.empty())
{
meshRegion_ = polyMesh::defaultRegion;
}
if (meshRegion_ != polyMesh::defaultRegion)
{
meshDir_ = meshRegion_/polyMesh::meshSubDir;
}
}
if (debug)
{
Info<< "fullCasePath=" << fullCasePath << nl
<< "FOAM_CASE=" << getEnv("FOAM_CASE") << nl
<< "FOAM_CASENAME=" << getEnv("FOAM_CASENAME") << endl;
}
// Create time object
dbPtr_.reset
(
new Time
(
Time::controlDictName,
fileName(fullCasePath.path()),
fileName(fullCasePath.name())
)
);
dbPtr_().functionObjects().off();
updateInfo();
}
// * * * * * * * * * * * * * * * * Destructor * * * * * * * * * * * * * * * //
Foam::vtkPV3blockMesh::~vtkPV3blockMesh()
{
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::~vtkPV3blockMesh" << endl;
}
// Hmm. pointNumberTextActors are not getting removed
//
forAll(pointNumberTextActorsPtrs_, pointI)
{
pointNumberTextActorsPtrs_[pointI]->Delete();
}
pointNumberTextActorsPtrs_.clear();
delete meshPtr_;
}
// * * * * * * * * * * * * * * * Member Functions * * * * * * * * * * * * * //
void Foam::vtkPV3blockMesh::updateInfo()
{
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateInfo"
<< " [meshPtr=" << (meshPtr_ ? "set" : "NULL") << "] " << endl;
}
resetCounters();
vtkDataArraySelection* blockSelection = reader_->GetBlockSelection();
vtkDataArraySelection* edgeSelection = reader_->GetCurvedEdgesSelection();
// enable 'internalMesh' on the first call
// or preserve the enabled selections
stringList enabledParts;
stringList enabledEdges;
bool firstTime = false;
if (!blockSelection->GetNumberOfArrays() && !meshPtr_)
{
firstTime = true;
}
else
{
enabledParts = getSelectedArrayEntries(blockSelection);
enabledEdges = getSelectedArrayEntries(edgeSelection);
}
// Clear current mesh parts list
blockSelection->RemoveAllArrays();
edgeSelection->RemoveAllArrays();
// need a blockMesh
updateFoamMesh();
// Update mesh parts list
updateInfoBlocks( blockSelection );
// Update curved edges list
updateInfoEdges( edgeSelection );
// restore the enabled selections
if (!firstTime)
{
setSelectedArrayEntries(blockSelection, enabledParts);
setSelectedArrayEntries(edgeSelection, enabledEdges);
}
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateInfo" << endl;
}
}
void Foam::vtkPV3blockMesh::updateFoamMesh()
{
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateFoamMesh" << endl;
}
// Check to see if the OpenFOAM mesh has been created
if (!meshPtr_)
{
if (debug)
{
Info<< "Creating blockMesh at time=" << dbPtr_().timeName()
<< endl;
}
// Set path for the blockMeshDict
const word dictName("blockMeshDict");
fileName dictPath(dbPtr_().system()/dictName);
// Check if dictionary is present in the constant directory
if
(
exists
(
dbPtr_().path()/dbPtr_().constant()
/polyMesh::meshSubDir/dictName
)
)
{
dictPath = dbPtr_().constant()/polyMesh::meshSubDir/dictName;
}
IOdictionary meshDict
(
IOobject
(
dictPath,
dbPtr_(),
IOobject::MUST_READ_IF_MODIFIED,
IOobject::NO_WRITE,
false
)
);
meshPtr_ = new blockMesh(meshDict, meshRegion_);
}
if (debug)
{
Info<< " Foam::vtkPV3blockMesh::updateFoamMesh" << endl;
}
}
void Foam::vtkPV3blockMesh::Update
(
vtkMultiBlockDataSet* output
)
{
reader_->UpdateProgress(0.1);
// Set up mesh parts selection(s)
updateBoolListStatus(blockStatus_, reader_->GetBlockSelection());
// Set up curved edges selection(s)
updateBoolListStatus(edgeStatus_, reader_->GetCurvedEdgesSelection());
reader_->UpdateProgress(0.2);
// Update the OpenFOAM mesh
updateFoamMesh();
reader_->UpdateProgress(0.5);
// Convert mesh elemente
int blockNo = 0;
convertMeshCorners(output, blockNo);
convertMeshBlocks(output, blockNo);
convertMeshEdges(output, blockNo);
reader_->UpdateProgress(0.8);
}
void Foam::vtkPV3blockMesh::CleanUp()
{
reader_->UpdateProgress(1.0);
}
void Foam::vtkPV3blockMesh::renderPointNumbers
(
vtkRenderer* renderer,
const bool show
)
{
// always remove old actors first
forAll(pointNumberTextActorsPtrs_, pointI)
{
renderer->RemoveViewProp(pointNumberTextActorsPtrs_[pointI]);
pointNumberTextActorsPtrs_[pointI]->Delete();
}
pointNumberTextActorsPtrs_.clear();
if (show && meshPtr_)
{
const pointField& cornerPts = meshPtr_->blockPointField();
const scalar scaleFactor = meshPtr_->scaleFactor();
pointNumberTextActorsPtrs_.setSize(cornerPts.size());
forAll(cornerPts, pointI)
{
vtkTextActor* txt = vtkTextActor::New();
txt->SetInput(Foam::name(pointI).c_str());
// Set text properties
vtkTextProperty* tprop = txt->GetTextProperty();
tprop->SetFontFamilyToArial();
tprop->BoldOn();
tprop->ShadowOff();
tprop->SetLineSpacing(1.0);
tprop->SetFontSize(14);
tprop->SetColor(1.0, 0.0, 1.0);
tprop->SetJustificationToCentered();
// Set text to use 3-D world co-ordinates
txt->GetPositionCoordinate()->SetCoordinateSystemToWorld();
txt->GetPositionCoordinate()->SetValue
(
cornerPts[pointI].x()*scaleFactor,
cornerPts[pointI].y()*scaleFactor,
cornerPts[pointI].z()*scaleFactor
);
// Add text to each renderer
renderer->AddViewProp(txt);
// Maintain a list of text labels added so that they can be
// removed later
pointNumberTextActorsPtrs_[pointI] = txt;
}
}
}
void Foam::vtkPV3blockMesh::PrintSelf(ostream& os, vtkIndent indent) const
{
#if 0
os << indent << "Number of nodes: "
<< (meshPtr_ ? meshPtr_->nPoints() : 0) << "\n";
os << indent << "Number of cells: "
<< (meshPtr_ ? meshPtr_->nCells() : 0) << "\n";
os << indent << "Number of available time steps: "
<< (dbPtr_.valid() ? dbPtr_().times().size() : 0) << endl;
#endif
}
// ************************************************************************* //