From 1ef88a2aefbec4a1fb6e0f87b9774fb199830d62 Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@Germany>
Date: Sun, 18 Oct 2009 17:50:41 +0200
Subject: [PATCH] blockMesh reader fix, start refactoring of PV3Readers

- apply scaleFactor (eg, mm->m) in PV3 reader - this looks better when
  overlaying with other objects

- stop segfault when paraview exits without deleting readers first
---
 .../graphics/PV3Readers/Allwmake              |  16 +
 .../PV3Readers/PV3FoamReader/Allwmake         |  24 +-
 .../PV3FoamReader/vtkPV3FoamReader.cxx        |  11 +
 .../PV3FoamReader/vtkPV3Foam/Make/options     |   6 +-
 .../PV3Readers/PV3blockMeshReader/Allwmake    |  24 +-
 .../vtkPV3blockMeshReader.cxx                 |  10 +
 .../vtkPV3blockMesh/Make/options              |   2 +
 .../vtkPV3blockMesh/vtkOpenFOAMPoints.H       |  15 +
 .../vtkPV3blockMesh/vtkPV3blockMesh.C         |   7 +-
 .../vtkPV3blockMesh/vtkPV3blockMeshConvert.C  |  20 +-
 .../PV3Readers/vtkPV3Readers/Make/files       |   3 +
 .../PV3Readers/vtkPV3Readers/Make/options     |  10 +
 .../PV3Readers/vtkPV3Readers/vtkPV3Readers.C  | 330 ++++++++++++++++++
 .../PV3Readers/vtkPV3Readers/vtkPV3Readers.H  | 229 ++++++++++++
 src/mesh/blockMesh/blockMesh/blockMesh.C      |   6 +
 src/mesh/blockMesh/blockMesh/blockMesh.H      |   6 +
 16 files changed, 687 insertions(+), 32 deletions(-)
 create mode 100755 applications/utilities/postProcessing/graphics/PV3Readers/Allwmake
 create mode 100644 applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files
 create mode 100644 applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options
 create mode 100644 applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C
 create mode 100644 applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H

diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake
new file mode 100755
index 00000000000..94a47b132b1
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/Allwmake
@@ -0,0 +1,16 @@
+#!/bin/sh
+cd ${0%/*} || exit 1    # run from this directory
+set -x
+
+if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
+then
+    case "$ParaView_VERSION" in
+    3*)
+        wmake libso vtkPV3Readers
+        PV3blockMeshReader/Allwmake
+        PV3FoamReader/Allwmake
+    ;;
+    esac
+fi
+
+# ----------------------------------------------------------------- end-of-file
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake
index c7a80fc7fbb..ef7b571102c 100755
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/Allwmake
@@ -4,18 +4,18 @@ set -x
 
 if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
 then
-   case "$ParaView_VERSION" in
-   3*)
-      wmake libso vtkPV3Foam
-      (
-         cd PV3FoamReader
-         mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
-         cd Make/$WM_OPTIONS
-         cmake ../..
-         make
-      )
-      ;;
-   esac
+    case "$ParaView_VERSION" in
+    3*)
+        wmake libso vtkPV3Foam
+        (
+            cd PV3FoamReader
+            mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
+            cd Make/$WM_OPTIONS
+            cmake ../..
+            make
+        )
+        ;;
+    esac
 fi
 
 # ----------------------------------------------------------------- end-of-file
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
index 28b9a2bc6fa..0b5c65dc784 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/PV3FoamReader/vtkPV3FoamReader.cxx
@@ -405,9 +405,20 @@ void vtkPV3FoamReader::updatePatchNamesView(const bool show)
 {
     pqApplicationCore* appCore = pqApplicationCore::instance();
 
+    // need to check this, since our destructor calls this
+    if (!appCore)
+    {
+        return;
+    }
+
     // Server manager model for querying items in the server manager
     pqServerManagerModel* smModel = appCore->getServerManagerModel();
 
+    if (!smModel)
+    {
+        return;
+    }
+
     // Get all the pqRenderView instances
     QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>();
 
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options
index 1e936c1d5de..d58afde30bd 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3FoamReader/vtkPV3Foam/Make/options
@@ -1,18 +1,20 @@
 EXE_INC = \
+    -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(LIB_SRC)/finiteVolume/lnInclude \
     -I$(LIB_SRC)/lagrangian/basic/lnInclude \
-    -I$(LIB_SRC)/meshTools/lnInclude \
     -I$(ParaView_DIR)/VTK \
     -I$(ParaView_INST_DIR) \
     -I$(ParaView_INST_DIR)/VTK \
     -I$(ParaView_INST_DIR)/VTK/Common \
     -I$(ParaView_INST_DIR)/VTK/Filtering \
     -I$(ParaView_INST_DIR)/VTK/Rendering \
+    -I../../vtkPV3Readers/lnInclude \
     -I../PV3FoamReader
 
 LIB_LIBS = \
+    -lvtkPV3Readers \
+    -lmeshTools \
     -lfiniteVolume \
     -lgenericPatchFields \
     -llagrangian \
-    -lmeshTools \
     $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake
index 3e2c407e6e1..443100d3810 100755
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/Allwmake
@@ -4,18 +4,18 @@ set -x
 
 if [ -d "$ParaView_DIR" -a -r "$ParaView_DIR" ]
 then
-   case "$ParaView_VERSION" in
-   3*)
-      wmake libso vtkPV3blockMesh
-      (
-         cd PV3blockMeshReader
-         mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
-         cd Make/$WM_OPTIONS
-         cmake ../..
-         make
-      )
-      ;;
-   esac
+    case "$ParaView_VERSION" in
+    3*)
+        wmake libso vtkPV3blockMesh
+        (
+            cd PV3blockMeshReader
+            mkdir -p Make/$WM_OPTIONS > /dev/null 2>&1
+            cd Make/$WM_OPTIONS
+            cmake ../..
+            make
+        )
+        ;;
+    esac
 fi
 
 # ----------------------------------------------------------------- end-of-file
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx
index 155fc83f57b..383deeecccb 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/PV3blockMeshReader/vtkPV3blockMeshReader.cxx
@@ -220,8 +220,18 @@ void vtkPV3blockMeshReader::updatePointNumbersView(const bool show)
 {
     pqApplicationCore* appCore = pqApplicationCore::instance();
 
+    // need to check this, since our destructor calls this
+    if (!appCore)
+    {
+        return;
+    }
+
     // Server manager model for querying items in the server manager
     pqServerManagerModel* smModel = appCore->getServerManagerModel();
+    if (!smModel)
+    {
+        return;
+    }
 
     // Get all the pqRenderView instances
     QList<pqRenderView*> renderViews = smModel->findItems<pqRenderView*>();
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options
index 2e5727ba771..5d19916934a 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/Make/options
@@ -7,9 +7,11 @@ EXE_INC = \
     -I$(ParaView_INST_DIR)/VTK/Common \
     -I$(ParaView_INST_DIR)/VTK/Filtering \
     -I$(ParaView_INST_DIR)/VTK/Rendering \
+    -I../../vtkPV3Readers/lnInclude \
     -I../PV3blockMeshReader
 
 LIB_LIBS = \
+    -lvtkPV3Readers \
     -lmeshTools \
     -lblockMesh \
     $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H
index b6fa0c83b0e..a8ce36e144e 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkOpenFOAMPoints.H
@@ -44,6 +44,21 @@ inline void vtkInsertNextOpenFOAMPoint
     points->InsertNextPoint(p.x(), p.y(), p.z());
 }
 
+inline void vtkInsertNextOpenFOAMPoint
+(
+    vtkPoints *points,
+    const Foam::point& p,
+    const Foam::scalar scaleFactor
+)
+{
+    points->InsertNextPoint
+    (
+        p.x()*scaleFactor,
+        p.y()*scaleFactor,
+        p.z()*scaleFactor
+    );
+}
+
 // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
 
 #endif
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C
index 66da31d620c..91424d3b577 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMesh.C
@@ -384,6 +384,7 @@ void Foam::vtkPV3blockMesh::renderPointNumbers
     if (show && meshPtr_)
     {
         const pointField& cornerPts = meshPtr_->blockPointField();
+        const scalar scaleFactor = meshPtr_->scaleFactor();
 
         pointNumberTextActorsPtrs_.setSize(cornerPts.size());
         forAll(cornerPts, pointI)
@@ -407,9 +408,9 @@ void Foam::vtkPV3blockMesh::renderPointNumbers
 
             txt->GetPositionCoordinate()->SetValue
             (
-                cornerPts[pointI].x(),
-                cornerPts[pointI].y(),
-                cornerPts[pointI].z()
+                cornerPts[pointI].x()*scaleFactor,
+                cornerPts[pointI].y()*scaleFactor,
+                cornerPts[pointI].z()*scaleFactor
             );
 
             // Add text to each renderer
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C
index c163ba14ed4..5ad588bb30f 100644
--- a/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/PV3blockMeshReader/vtkPV3blockMesh/vtkPV3blockMeshConvert.C
@@ -66,6 +66,7 @@ void Foam::vtkPV3blockMesh::convertMeshBlocks
     }
 
     int blockI = 0;
+    const scalar scaleFactor = blkMesh.scaleFactor();
 
     for
     (
@@ -103,7 +104,8 @@ void Foam::vtkPV3blockMesh::convertMeshBlocks
             vtkInsertNextOpenFOAMPoint
             (
                 vtkpoints,
-                blockPoints[blockLabels[ptI]]
+                blockPoints[blockLabels[ptI]],
+                scaleFactor
             );
 
             nodeIds[ptI] = ptI;
@@ -159,6 +161,7 @@ void Foam::vtkPV3blockMesh::convertMeshEdges
     const curvedEdgeList& edges = blkMesh.edges();
 
     int edgeI = 0;
+    const scalar scaleFactor = blkMesh.scaleFactor();
 
     for
     (
@@ -212,7 +215,12 @@ void Foam::vtkPV3blockMesh::convertMeshEdges
                 vtkIdType pointIds[edgePoints.size()];
                 forAll(edgePoints, ptI)
                 {
-                    vtkInsertNextOpenFOAMPoint(vtkpoints, edgePoints[ptI]);
+                    vtkInsertNextOpenFOAMPoint
+                    (
+                        vtkpoints,
+                        edgePoints[ptI],
+                        scaleFactor
+                    );
                     pointIds[ptI] = ptI;
                 }
 
@@ -266,6 +274,7 @@ void Foam::vtkPV3blockMesh::convertMeshCorners
     label datasetNo = 0;       // restart at dataset 0
 
     const pointField& blockPoints = meshPtr_->blockPointField();
+    const scalar& scaleFactor = meshPtr_->scaleFactor();
 
     if (debug)
     {
@@ -284,7 +293,12 @@ void Foam::vtkPV3blockMesh::convertMeshCorners
         vtkIdType pointId = 0;
         forAll(blockPoints, ptI)
         {
-            vtkInsertNextOpenFOAMPoint(vtkpoints, blockPoints[ptI]);
+            vtkInsertNextOpenFOAMPoint
+            (
+                vtkpoints,
+                blockPoints[ptI],
+                scaleFactor
+            );
 
             vtkcells->InsertNextCell(1, &pointId);
             pointId++;
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files
new file mode 100644
index 00000000000..134b8de963e
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/files
@@ -0,0 +1,3 @@
+vtkPV3Readers.C
+
+LIB = $(FOAM_LIBBIN)/libvtkPV3Readers
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options
new file mode 100644
index 00000000000..876a3e334ed
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/Make/options
@@ -0,0 +1,10 @@
+EXE_INC = \
+    -I$(ParaView_DIR)/VTK \
+    -I$(ParaView_INST_DIR) \
+    -I$(ParaView_INST_DIR)/VTK \
+    -I$(ParaView_INST_DIR)/VTK/Common \
+    -I$(ParaView_INST_DIR)/VTK/Filtering \
+    -I$(ParaView_INST_DIR)/VTK/Rendering
+
+LIB_LIBS = \
+    $(GLIBS)
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C
new file mode 100644
index 00000000000..ed10463f91f
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.C
@@ -0,0 +1,330 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Description
+    Misc helper methods and utilities
+
+\*---------------------------------------------------------------------------*/
+
+#include "vtkPV3Readers.H"
+
+// Foam includes
+#include "IFstream.H"
+
+// VTK includes
+#include "vtkDataArraySelection.h"
+#include "vtkDataSet.h"
+#include "vtkMultiBlockDataSet.h"
+#include "vtkInformation.h"
+
+// * * * * * * * * * * * * * * Static Data Members * * * * * * * * * * * * * //
+
+defineTypeNameAndDebug(Foam::vtkPV3Readers, 0);
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+    //! @cond fileScope
+    //  Extract up to the first non-word characters
+    inline word getFirstWord(const char* str)
+    {
+        if (str)
+        {
+            label n = 0;
+            while (str[n] && word::valid(str[n]))
+            {
+                ++n;
+            }
+            return word(str, n, true);
+        }
+        else
+        {
+            return word::null;
+        }
+
+    }
+    //! @endcond fileScope
+
+} // End namespace Foam
+
+
+// * * * * * * * * * * * * * Private Member Functions  * * * * * * * * * * * //
+
+void Foam::vtkPV3Readers::AddToBlock
+(
+    vtkMultiBlockDataSet* output,
+    vtkDataSet* dataset,
+    const partInfo& selector,
+    const label datasetNo,
+    const std::string& datasetName
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+
+    if (!block)
+    {
+        if (blockDO)
+        {
+            FatalErrorIn("Foam::vtkPV3Readers::AddToBlock")
+                << "Block already has a vtkDataSet assigned to it"
+                << endl;
+            return;
+        }
+
+        block = vtkMultiBlockDataSet::New();
+        output->SetBlock(blockNo, block);
+        block->Delete();
+    }
+
+    if (debug)
+    {
+        Info<< "block[" << blockNo << "] has "
+            << block->GetNumberOfBlocks()
+            <<  " datasets prior to adding set " << datasetNo
+            <<  " with name: " << datasetName << endl;
+    }
+
+    block->SetBlock(datasetNo, dataset);
+
+    // name the block when assigning dataset 0
+    if (datasetNo == 0)
+    {
+        output->GetMetaData(blockNo)->Set
+        (
+            vtkCompositeDataSet::NAME(),
+            selector.name()
+        );
+    }
+
+    if (datasetName.size())
+    {
+        block->GetMetaData(datasetNo)->Set
+        (
+            vtkCompositeDataSet::NAME(),
+            datasetName.c_str()
+        );
+    }
+}
+
+
+vtkDataSet* Foam::vtkPV3Readers::GetDataSetFromBlock
+(
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector,
+    const label datasetNo
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+
+    if (block)
+    {
+        return vtkDataSet::SafeDownCast(block->GetBlock(datasetNo));
+    }
+
+    return 0;
+}
+
+
+// ununsed at the moment
+Foam::label Foam::vtkPV3Readers::GetNumberOfDataSets
+(
+    vtkMultiBlockDataSet* output,
+    const partInfo& selector
+)
+{
+    const int blockNo = selector.block();
+
+    vtkDataObject* blockDO = output->GetBlock(blockNo);
+    vtkMultiBlockDataSet* block = vtkMultiBlockDataSet::SafeDownCast(blockDO);
+    if (block)
+    {
+        return block->GetNumberOfBlocks();
+    }
+
+    return 0;
+}
+
+
+// Foam::word Foam::vtkPV3Readers::getPartName(int partId)
+// {
+//     return getFirstWord(reader_->GetPartArrayName(partId));
+// }
+
+
+Foam::wordHashSet Foam::vtkPV3Readers::getSelected
+(
+    vtkDataArraySelection* select
+)
+{
+    int nElem = select->GetNumberOfArrays();
+    wordHashSet selections(2*nElem);
+
+    for (int elemI=0; elemI < nElem; ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections.insert(getFirstWord(select->GetArrayName(elemI)));
+        }
+    }
+
+    return selections;
+}
+
+
+Foam::wordHashSet Foam::vtkPV3Readers::getSelected
+(
+    vtkDataArraySelection* select,
+    const partInfo& selector
+)
+{
+    int nElem = select->GetNumberOfArrays();
+    wordHashSet selections(2*nElem);
+
+    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections.insert(getFirstWord(select->GetArrayName(elemI)));
+        }
+    }
+
+    return selections;
+}
+
+
+Foam::stringList Foam::vtkPV3Readers::getSelectedArrayEntries
+(
+    vtkDataArraySelection* select
+)
+{
+    stringList selections(select->GetNumberOfArrays());
+    label nElem = 0;
+
+    forAll(selections, elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections[nElem++] = select->GetArrayName(elemI);
+        }
+    }
+    selections.setSize(nElem);
+
+
+    if (debug)
+    {
+        label nElem = select->GetNumberOfArrays();
+        Info<< "available(";
+        for (int elemI = 0; elemI < nElem; ++elemI)
+        {
+            Info<< " \"" << select->GetArrayName(elemI) << "\"";
+        }
+        Info<< " )\nselected(";
+
+        forAll(selections, elemI)
+        {
+            Info<< " " << selections[elemI];
+        }
+        Info<< " )\n";
+    }
+
+    return selections;
+}
+
+
+Foam::stringList Foam::vtkPV3Readers::getSelectedArrayEntries
+(
+    vtkDataArraySelection* select,
+    const partInfo& selector
+)
+{
+    stringList selections(selector.size());
+    label nElem = 0;
+
+    for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+    {
+        if (select->GetArraySetting(elemI))
+        {
+            selections[nElem++] = select->GetArrayName(elemI);
+        }
+    }
+    selections.setSize(nElem);
+
+
+    if (debug)
+    {
+        Info<< "available(";
+        for (int elemI = selector.start(); elemI < selector.end(); ++elemI)
+        {
+            Info<< " \"" << select->GetArrayName(elemI) << "\"";
+        }
+        Info<< " )\nselected(";
+
+        forAll(selections, elemI)
+        {
+            Info<< " " << selections[elemI];
+        }
+        Info<< " )\n";
+    }
+
+    return selections;
+}
+
+
+void Foam::vtkPV3Readers::setSelectedArrayEntries
+(
+    vtkDataArraySelection* select,
+    const stringList& selections
+)
+{
+    const int nElem = select->GetNumberOfArrays();
+    select->DisableAllArrays();
+
+    // Loop through entries, setting values from selectedEntries
+    for (int elemI=0; elemI < nElem; ++elemI)
+    {
+        string arrayName(select->GetArrayName(elemI));
+
+        forAll(selections, elemI)
+        {
+            if (selections[elemI] == arrayName)
+            {
+                select->EnableArray(arrayName.c_str());
+                break;
+            }
+        }
+    }
+}
+
+
+// * * * * * * * * * * * * * * * Member Functions  * * * * * * * * * * * * * //
+
+
+// ************************************************************************* //
diff --git a/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H
new file mode 100644
index 00000000000..fba4da5d948
--- /dev/null
+++ b/applications/utilities/postProcessing/graphics/PV3Readers/vtkPV3Readers/vtkPV3Readers.H
@@ -0,0 +1,229 @@
+/*---------------------------------------------------------------------------*\
+  =========                 |
+  \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
+   \\    /   O peration     |
+    \\  /    A nd           | Copyright (C) 1991-2009 OpenCFD Ltd.
+     \\/     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 2 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, write to the Free Software Foundation,
+    Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+Namespace
+    Foam::vtkPV3Readers
+
+Description
+    A collection of helper functions when building a reader interface in
+    ParaView3.
+
+SourceFiles
+    vtkPV3Readers.C
+
+\*---------------------------------------------------------------------------*/
+
+#ifndef vtkPV3Readers_H
+#define vtkPV3Readers_H
+
+// do not include legacy strstream headers
+#ifndef  VTK_EXCLUDE_STRSTREAM_HEADERS
+# define VTK_EXCLUDE_STRSTREAM_HEADERS
+#endif
+
+#include "className.H"
+#include "fileName.H"
+#include "stringList.H"
+#include "wordList.H"
+#include "HashSet.H"
+
+
+// * * * * * * * * * * * * * Forward Declarations  * * * * * * * * * * * * * //
+
+class vtkDataArraySelection;
+class vtkDataSet;
+class vtkPoints;
+class vtkPV3FoamReader;
+class vtkRenderer;
+class vtkTextActor;
+class vtkMultiBlockDataSet;
+class vtkPolyData;
+class vtkUnstructuredGrid;
+class vtkIndent;
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+namespace Foam
+{
+namespace vtkPV3Readers 
+{
+    //- Declare name of the class and its debug switch
+    NamespaceName("vtkPV3Readers");
+
+    //- Bookkeeping for GUI checklists and the multi-block organization
+    class partInfo
+    {
+        const char *name_;
+        int block_;
+        int start_;
+        int size_;
+
+    public:
+
+        partInfo(const char *name, const int blockNo=0)
+        :
+            name_(name),
+            block_(blockNo),
+            start_(-1),
+            size_(0)
+        {}
+
+        //- Return the block holding these datasets
+        int block() const
+        {
+            return block_;
+        }
+
+        //- Assign block number, return previous value
+        int block(int blockNo)
+        {
+            int prev = block_;
+            block_ = blockNo;
+            return prev;
+        }
+
+        const char* name() const
+        {
+            return name_;
+        }
+
+        int start() const
+        {
+            return start_;
+        }
+
+        int end() const
+        {
+            return start_ + size_;
+        }
+
+        int size() const
+        {
+            return size_;
+        }
+
+        bool empty() const
+        {
+            return !size_;
+        }
+
+        void reset()
+        {
+            start_ = -1;
+            size_ = 0;
+        }
+
+        //- Assign new start and reset the size
+        void operator=(const int i)
+        {
+            start_ = i;
+            size_ = 0;
+        }
+
+        //- Increment the size
+        void operator+=(const int n)
+        {
+            size_ += n;
+        }
+    };
+
+
+    //- Convenience method use to convert the readers from VTK 5
+    //  multiblock API to the current composite data infrastructure
+    void AddToBlock
+    (
+        vtkMultiBlockDataSet* output,
+        vtkDataSet* dataset,
+        const partInfo& selector,
+        const label datasetNo,
+        const std::string& datasetName
+    );
+
+
+    //- Convenience method use to convert the readers from VTK 5
+    // multiblock API to the current composite data infrastructure
+    vtkDataSet* GetDataSetFromBlock
+    (
+        vtkMultiBlockDataSet* output,
+        const partInfo& selector,
+        const label datasetNo
+    );
+
+    //- Convenience method use to convert the readers from VTK 5
+    // multiblock API to the current composite data infrastructure
+    // ununsed at the moment
+    label GetNumberOfDataSets
+    (
+        vtkMultiBlockDataSet* output,
+        const partInfo& selector
+    );
+
+
+    //- Retrieve the current selections as a wordHashSet
+    wordHashSet getSelected
+    (
+        vtkDataArraySelection* select
+    );
+
+
+    //- Retrieve a sub-list of the current selections
+    wordHashSet getSelected
+    (
+        vtkDataArraySelection*,
+        const partInfo&
+    );
+
+
+    //- Retrieve the current selections
+    stringList getSelectedArrayEntries(vtkDataArraySelection*);
+
+    //- Retrieve a sub-list of the current selections
+    stringList getSelectedArrayEntries
+    (
+        vtkDataArraySelection* select,
+        const partInfo& selector
+    );
+
+
+    //- Set selection(s)
+    void setSelectedArrayEntries
+    (
+        vtkDataArraySelection*,
+        const stringList&
+    );
+
+
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+} // End namespace vtkPV3
+
+} // End namespace Foam
+
+// * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * //
+
+#endif
+
+// ************************************************************************* //
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.C b/src/mesh/blockMesh/blockMesh/blockMesh.C
index 4d499ea9432..1ed0d44a7e0 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.C
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.C
@@ -78,6 +78,12 @@ const Foam::polyMesh& Foam::blockMesh::topology() const
 }
 
 
+Foam::scalar Foam::blockMesh::scaleFactor() const
+{
+    return scaleFactor_;
+}
+
+
 const Foam::pointField& Foam::blockMesh::points() const
 {
     if (points_.empty())
diff --git a/src/mesh/blockMesh/blockMesh/blockMesh.H b/src/mesh/blockMesh/blockMesh/blockMesh.H
index 6e67506a798..0c423a9b832 100644
--- a/src/mesh/blockMesh/blockMesh/blockMesh.H
+++ b/src/mesh/blockMesh/blockMesh/blockMesh.H
@@ -144,6 +144,7 @@ public:
         // Access
 
             //- Reference to point field defining the block mesh
+            //  these points have not been scaled by scaleFactor
             const pointField& blockPointField() const;
 
             const polyMesh& topology() const;
@@ -153,6 +154,11 @@ public:
                 return edges_;
             }
 
+            //- The scaling factor used to convert to meters
+            scalar scaleFactor() const;
+
+            //- The points for the entire mesh
+            //  these points have been scaled by scaleFactor
             const pointField& points() const;
 
             const cellShapeList& cells() const;
-- 
GitLab