From b30138595c0efd59ea265c7cb508579335e881cf Mon Sep 17 00:00:00 2001
From: Mark Olesen <Mark.Olesen@esi-group.com>
Date: Fri, 15 Jun 2018 23:01:27 +0200
Subject: [PATCH] ENH: adjustments to runTimePostProcessing

- support VTP input in functionObjectCloud scene element

- additional fallback lookup of cloud information from state properties
  instead of cloud OutputProperties
---
 .../CMakeLists-Common.txt                     |  3 +
 .../functionObjectBase.C                      | 18 ++--
 .../functionObjectBase.H                      | 44 ++++++++--
 .../functionObjectCloud.C                     | 86 ++++++++++++-------
 .../functionObjectCloud.H                     |  6 +-
 .../functionObjectLine.C                      |  2 +-
 .../functionObjectSurface.C                   | 39 ++++-----
 .../runTimePostProcessing/geometrySurface.C   |  2 +-
 8 files changed, 129 insertions(+), 71 deletions(-)

diff --git a/src/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt b/src/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt
index 9dc15138fde..55effddcd5f 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt
+++ b/src/functionObjects/graphics/runTimePostProcessing/CMakeLists-Common.txt
@@ -15,6 +15,7 @@ include_directories(
     $ENV{WM_PROJECT_DIR}/src/OSspecific/$ENV{WM_OSTYPE}/lnInclude
     $ENV{WM_PROJECT_DIR}/src/surfMesh/lnInclude
     $ENV{WM_PROJECT_DIR}/src/finiteVolume/lnInclude
+    $ENV{WM_PROJECT_DIR}/src/conversion/lnInclude
     ${CMAKE_CURRENT_SOURCE_DIR}
     ${CMAKE_CURRENT_BINARY_DIR}
 )
@@ -58,6 +59,7 @@ file(GLOB SOURCE_FILES
     functionObjectLine.C
     functionObjectSurface.C
     geometryBase.C
+    geometryPatches.C
     geometrySurface.C
     pathline.C
     pointData.C
@@ -72,6 +74,7 @@ set(OPENFOAM_LIBRARIES
     OpenFOAM
     surfMesh
     finiteVolume
+    conversion
 )
 
 add_library(
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.C
index df8fb3383a1..5ca9cac31d6 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.C
@@ -44,11 +44,11 @@ namespace runTimePostPro
 bool Foam::functionObjects::runTimePostPro::functionObjectBase::removeFile
 (
     const word& keyword,
-    const word& fieldName
+    const word& subDictName
 )
 {
     dictionary dict;
-    state_.getObjectDict(functionObjectName_, fieldName, dict);
+    state_.getObjectDict(functionObjectName_, subDictName, dict);
 
     fileName fName;
     if (dict.readIfPresent(keyword, fName))
@@ -65,15 +65,13 @@ Foam::fileName
 Foam::functionObjects::runTimePostPro::functionObjectBase::getFileName
 (
     const word& keyword,
-    const word& fieldName
+    const word& subDictName
 ) const
 {
     dictionary dict;
-    state_.getObjectDict(functionObjectName_, fieldName, dict);
+    state_.getObjectDict(functionObjectName_, subDictName, dict);
 
-    fileName fName(dict.lookupOrDefault(keyword, fileName::null));
-
-    return fName;
+    return dict.lookupOrDefault<fileName>(keyword, fileName::null);
 }
 
 
@@ -88,11 +86,9 @@ Foam::functionObjects::runTimePostPro::functionObjectBase::functionObjectBase
 :
     fieldVisualisationBase(dict, colours),
     state_(state),
-    functionObjectName_(""),
+    functionObjectName_(dict.lookup("functionObject")),
     clearObjects_(dict.lookupOrDefault("clearObjects", false))
-{
-    dict.lookup("functionObject") >> functionObjectName_;
-}
+{}
 
 
 // * * * * * * * * * * * * * * * * Destructor  * * * * * * * * * * * * * * * //
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.H b/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.H
index b04e44bb9bc..042873e40a4 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.H
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectBase.H
@@ -27,6 +27,13 @@ Class
 Description
     Base class for function object visualisation
 
+    Dictionary controls
+    \table
+        Property     | Description                      | Required    | Default
+        functionObject | The data source                | yes         |
+        clearObjects  | Remove file after use           | no          | no
+    \endtable
+
 SourceFiles
     functionObjectBase.C
 
@@ -73,7 +80,7 @@ protected:
         //- Reference to the state
         const stateFunctionObject& state_;
 
-        //- Function object name
+        //- The function object name which provides the source data
         word functionObjectName_;
 
         //- Flag to indicate that source data should be cleared after use
@@ -82,11 +89,36 @@ protected:
 
     // Protected Member Functions
 
-        //- Retrieve file used to create the scene object
-        fileName getFileName(const word& keyword, const word& fieldName) const;
-
-        //- Remove file used to create the scene object
-        bool removeFile(const word& keyword, const word& fieldName);
+        //- Retrieve the filename used to create the scene object
+        //- using information stored via the stateFunctionObject.
+        //
+        //  \param keyword is normally "file"
+        //  \param subDictName is the sub-dictionary name, which is often
+        //     the fieldName when one file is used per field.
+        //
+        //  Eg,
+        //  \verbatim
+        //      T
+        //      {
+        //          file    "path/T_object.vtk";
+        //      }
+        //      defaultCloud
+        //      {
+        //          file    "path/cloud_0001.vtp";
+        //          fields  (T U);
+        //      }
+        //  \endverbatim
+        fileName getFileName
+        (
+            const word& keyword,
+            const word& subDictName
+        ) const;
+
+        //- Remove file used to create the scene object.
+        //  Same naming semantics as getFileName.
+        //
+        //  \note does not change the stateFunctionObject
+        bool removeFile(const word& keyword, const word& subDictName);
 
 
 public:
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C
index f4fe22be99e..06c6e2114be 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.C
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2015-2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2015-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -28,12 +28,15 @@ License
 #include "fvMesh.H"
 #include "runTimePostProcessing.H"
 #include "addToRunTimeSelectionTable.H"
+#include "stringOps.H"
 
 // VTK includes
 #include "vtkActor.h"
 #include "vtkRenderer.h"
 #include "vtkSmartPointer.h"
+#include "vtkPolyData.h"
 #include "vtkPolyDataMapper.h"
+#include "vtkXMLPolyDataReader.h"
 #include "vtkPolyDataReader.h"
 #include "vtkProperty.h"
 
@@ -64,6 +67,7 @@ Foam::functionObjects::runTimePostPro::functionObjectCloud::functionObjectCloud
     pointData(parent, dict, colours),
     functionObjectBase(parent, dict, colours),
     cloudName_(dict.lookup("cloud")),
+    inputFileName_(),
     colourFieldName_(dict.lookup("colourField")),
     actor_()
 {
@@ -92,23 +96,42 @@ addGeometryToScene
         return;
     }
 
+    inputFileName_.clear();
+
+    // The CloudToVTK functionObject from
+    //
+    //   lagrangian/intermediate/submodels/CloudFunctionObjects/
+    //
+    // stores file state on cloud OutputProperties itself,
+    //
+    // whereas the vtkCloud functionObject treats it like other
+    // output and stores via the stateFunctionObject.
+    // Since it uses VTP format, there is only a single file with all fields
+    // - lookup by cloudName.
+
     const dictionary& cloudDict =
         geometryBase::parent_.mesh().lookupObject<IOdictionary>
         (
             cloudName_ + "OutputProperties"
         );
 
-    fileName fName;
-    if (cloudDict.found("functionObjectCloud"))
+    if (cloudDict.found("cloudFunctionObject"))
     {
         const dictionary& foDict = cloudDict.subDict("cloudFunctionObject");
         if (foDict.found(functionObjectName_))
         {
-            foDict.subDict(functionObjectName_).readIfPresent("file", fName);
+            foDict.subDict(functionObjectName_)
+                .readIfPresent("file", inputFileName_);
         }
     }
+    else
+    {
+        inputFileName_ = getFileName("file", cloudName_);
+    }
 
-    if (fName.empty())
+
+    stringOps::inplaceExpand(inputFileName_);
+    if (inputFileName_.empty())
     {
         WarningInFunction
             << "Unable to find function object " << functionObjectName_
@@ -118,12 +141,32 @@ addGeometryToScene
         return;
     }
 
-    if (fName.ext() == "vtk")
+    vtkSmartPointer<vtkPolyData> dataset;
+
+    if (inputFileName_.hasExt("vtp"))
     {
-        auto points = vtkSmartPointer<vtkPolyDataReader>::New();
-        points->SetFileName(fName.c_str());
-        points->Update();
+        auto reader = vtkSmartPointer<vtkXMLPolyDataReader>::New();
+        reader->SetFileName(inputFileName_.c_str());
+        reader->Update();
 
+        dataset = reader->GetOutput();
+    }
+    else if (inputFileName_.hasExt("vtk"))
+    {
+        auto reader = vtkSmartPointer<vtkPolyDataReader>::New();
+        reader->SetFileName(inputFileName_.c_str());
+        reader->Update();
+
+        dataset = reader->GetOutput();
+    }
+    else
+    {
+        // Invalid name - ignore
+        inputFileName_.clear();
+    }
+
+    if (dataset)
+    {
         auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
 
         actor_->SetMapper(mapper);
@@ -134,7 +177,7 @@ addGeometryToScene
             fieldName_,
             colourFieldName_,
             maxGlyphLength_,
-            points->GetOutput(),
+            dataset,
             actor_,
             renderer
         );
@@ -160,27 +203,10 @@ bool Foam::functionObjects::runTimePostPro::functionObjectCloud::clear()
 {
     if (functionObjectBase::clear())
     {
-        const dictionary& cloudDict =
-            geometryBase::parent_.mesh().lookupObject<IOdictionary>
-            (
-                cloudName_ & "OutputProperties"
-            );
-
-        if (cloudDict.found("functionObjectCloud"))
+        if (inputFileName_.size() && Foam::rm(inputFileName_))
         {
-            const dictionary& foDict = cloudDict.subDict("functionObjectCloud");
-            if (foDict.found(functionObjectName_))
-            {
-                const dictionary& functionDict =
-                    foDict.subDict(functionObjectName_);
-
-                fileName fName;
-                if (functionDict.readIfPresent("file", fName))
-                {
-                    Foam::rm(fName);
-                    return true;
-                }
-            }
+            inputFileName_.clear();
+            return true;
         }
     }
 
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H b/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H
index e40489ef143..74888b234d0 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectCloud.H
@@ -3,7 +3,7 @@
   \\      /  F ield         | OpenFOAM: The Open Source CFD Toolbox
    \\    /   O peration     |
     \\  /    A nd           | Copyright (C) 2015 OpenFOAM Foundation
-     \\/     M anipulation  | Copyright (C) 2016 OpenCFD Ltd.
+     \\/     M anipulation  | Copyright (C) 2016-2018 OpenCFD Ltd.
 -------------------------------------------------------------------------------
 License
     This file is part of OpenFOAM.
@@ -74,13 +74,15 @@ protected:
         //- Name of functionObjectCloud
         word cloudName_;
 
+        //- The input filename used
+        fileName inputFileName_;
+
         //- Name of field to colour by
         word colourFieldName_;
 
         //- Actor
         vtkSmartPointer<vtkActor> actor_;
 
-
 public:
 
     //- Run-time type information
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
index 2d7fc469400..ca0ba78ac8e 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectLine.C
@@ -99,7 +99,7 @@ addGeometryToScene
         return;
     }
 
-    if (fName.ext() == "vtk")
+    if (fName.hasExt("vtk"))
     {
         auto lines = vtkSmartPointer<vtkPolyDataReader>::New();
         lines->SetFileName(fName.c_str());
diff --git a/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C b/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
index 22b9c7570e5..1d2e4d737a0 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/functionObjectSurface.C
@@ -115,34 +115,33 @@ addGeometryToScene
             surfaceActor_,
             renderer
         );
+        return;
     }
-    else
+
+    if (fName.hasExt("vtk"))
     {
-        if (fName.ext() == "vtk")
-        {
-            auto surf = vtkSmartPointer<vtkPolyDataReader>::New();
-            surf->SetFileName(fName.c_str());
-            surf->Update();
+        auto surf = vtkSmartPointer<vtkPolyDataReader>::New();
+        surf->SetFileName(fName.c_str());
+        surf->Update();
 
-            addFeatureEdges(renderer, surf->GetOutput());
+        addFeatureEdges(renderer, surf->GetOutput());
 
-            auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
-            mapper->SetInputConnection(surf->GetOutputPort());
+        auto mapper = vtkSmartPointer<vtkPolyDataMapper>::New();
+        mapper->SetInputConnection(surf->GetOutputPort());
 
-            setField(position, fieldName_, mapper, renderer, surf->GetOutput());
+        setField(position, fieldName_, mapper, renderer, surf->GetOutput());
 
-            surfaceActor_->SetMapper(mapper);
+        surfaceActor_->SetMapper(mapper);
 
-            setRepresentation(surfaceActor_);
+        setRepresentation(surfaceActor_);
 
-            renderer->AddActor(surfaceActor_);
-        }
-        else
-        {
-            WarningInFunction
-                << "Only VTK file types are supported"
-                << endl;
-        }
+        renderer->AddActor(surfaceActor_);
+    }
+    else
+    {
+        WarningInFunction
+            << "Only VTK file types are supported"
+            << endl;
     }
 }
 
diff --git a/src/functionObjects/graphics/runTimePostProcessing/geometrySurface.C b/src/functionObjects/graphics/runTimePostProcessing/geometrySurface.C
index 7c688932221..8c890980dc5 100644
--- a/src/functionObjects/graphics/runTimePostProcessing/geometrySurface.C
+++ b/src/functionObjects/graphics/runTimePostProcessing/geometrySurface.C
@@ -71,7 +71,7 @@ void Foam::functionObjects::runTimePostPro::geometrySurface::addGeometryToScene
     {
         FatalErrorInFunction
             << "Glyph representation not available for " << typeName
-            << "object" << exit(FatalError);
+            << " object" << exit(FatalError);
     }
 
     triSurface surf(fName);
-- 
GitLab