Salome HOME
Merge branch 'V8_0_BR' V8_0_0a2
authorvsr <vsr@opencascade.com>
Fri, 15 Jan 2016 06:27:26 +0000 (09:27 +0300)
committervsr <vsr@opencascade.com>
Fri, 15 Jan 2016 06:27:26 +0000 (09:27 +0300)
36 files changed:
src/Plugins/CMakeLists.txt
src/Plugins/GhostCellsGenerator/CMakeLists.txt [new file with mode: 0644]
src/Plugins/GhostCellsGenerator/GhostCellsGenerator.xml [new file with mode: 0644]
src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx [new file with mode: 0644]
src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.h [new file with mode: 0644]
src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.cxx [new file with mode: 0644]
src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.h [new file with mode: 0644]
src/Plugins/JSONReader/CMakeLists.txt
src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt
src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx
src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h
src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx
src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx
src/Plugins/MEDReader/IO/vtkExtractGroup.cxx
src/Plugins/MEDReader/IO/vtkExtractGroup.h
src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.cxx
src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.h
src/Plugins/MEDReader/Test/Baselines/testMEDReader0.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader10.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader11.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader12.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader13.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader14.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader15.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader19.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader2.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader3.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader4.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader5.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader6.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader7.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/Baselines/testMEDReader8.png [new file with mode: 0644]
src/Plugins/MEDReader/Test/CMakeLists.txt
src/Plugins/MEDReader/Test/testMEDReader18.py
src/Plugins/MEDReader/Test/testMEDReader19.py [new file with mode: 0644]
src/Plugins/ParaMEDCorba/vtkParaMEDCorbaSource.cxx

index ff1b52b3cda603031de308ddad5c125cd2e818fe..8fca10f7339a49190f06a97a311146a4155a4f83 100755 (executable)
@@ -23,6 +23,7 @@ SET(_subdirs
   MEDReader
 #  TableReader
   ElevationSurface
+  GhostCellsGenerator
   ScaleVector
   EllipseBuilder
   DifferenceTimesteps
diff --git a/src/Plugins/GhostCellsGenerator/CMakeLists.txt b/src/Plugins/GhostCellsGenerator/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d66a945
--- /dev/null
@@ -0,0 +1,23 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
+
+PROJECT(GhostCellsGenerator)
+
+FIND_PACKAGE(ParaView REQUIRED)
+INCLUDE(${PARAVIEW_USE_FILE})
+
+IF(PARAVIEW_USE_MPI)
+# Necessary while this class is not in VTK
+  SET(SOURCES vtkPUnstructuredGridGhostCellsGenerator.cxx)
+ENDIF(PARAVIEW_USE_MPI)
+
+ADD_PARAVIEW_PLUGIN(GhostCellsGenerator "1.0"
+  SERVER_MANAGER_SOURCES vtkPVUnstructuredGridGhostCellsGenerator.cxx
+  SERVER_MANAGER_XML GhostCellsGenerator.xml
+  SOURCES ${SOURCES}
+  REQUIRED_ON_SERVER)
+
+INSTALL( TARGETS GhostCellsGenerator 
+  RUNTIME DESTINATION lib/paraview
+  LIBRARY DESTINATION lib/paraview
+  ARCHIVE DESTINATION lib/paraview
+  )
diff --git a/src/Plugins/GhostCellsGenerator/GhostCellsGenerator.xml b/src/Plugins/GhostCellsGenerator/GhostCellsGenerator.xml
new file mode 100644 (file)
index 0000000..f6990b5
--- /dev/null
@@ -0,0 +1,44 @@
+<ServerManagerConfiguration>
+  <ProxyGroup name="filters">
+    <SourceProxy class="vtkPVUnstructuredGridGhostCellsGenerator"
+                 label="Generate Ghost Cells"
+                 name="GhostCellGenerator">
+      <Documentation long_help="Generate ghost cells for unstructured grids. Global point ids array is required.">
+      </Documentation>
+      <InputProperty command="SetInputConnection"
+                     name="Input">
+        <ProxyGroupDomain name="groups">
+          <Group name="sources" />
+          <Group name="filters" />
+        </ProxyGroupDomain>
+        <DataTypeDomain name="input_type">
+          <DataType value="vtkUnstructuredGrid" />
+          <DataType value="vtkCompositeDataSet" />
+        </DataTypeDomain>
+        <Documentation>This property specifies the input to the ghost cells generator.</Documentation>
+      </InputProperty>
+      <IntVectorProperty command="SetUseGlobalPointIds"
+                         default_values="1"
+                         name="UseGlobalIds"
+                         number_of_elements="1"
+                         panel_visibility="default">
+        <Documentation>Specify if the filter must take benefit of global point ids if they exist or if
+          point coordinates should be used instead.</Documentation>
+        <BooleanDomain name="bool" />
+      </IntVectorProperty>
+      <StringVectorProperty command="SetGlobalPointIdsArrayName"
+                            default_values="GlobalNodeIds"
+                            name="GlobalPointIdsArrayName"
+                            number_of_elements="1"
+                            panel_visibility="default">
+        <Documentation>This property provides a name for the input array
+        containing the global point ids if the GlobalIds array of the point data if not set.</Documentation>
+        <Hints>
+          <PropertyWidgetDecorator type="ShowWidgetDecorator">
+            <Property name="UseGlobalIds" function="boolean" />
+          </PropertyWidgetDecorator>
+        </Hints>
+      </StringVectorProperty>
+    </SourceProxy>
+  </ProxyGroup>
+</ServerManagerConfiguration>
diff --git a/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx b/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx
new file mode 100644 (file)
index 0000000..7cfcf9e
--- /dev/null
@@ -0,0 +1,581 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPUnstructuredGridGhostCellsGenerator.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkPUnstructuredGridGhostCellsGenerator.h"
+
+#include "vtkCellArray.h"
+#include "vtkCharArray.h"
+#include "vtkDataSetSurfaceFilter.h"
+#include "vtkExtractCells.h"
+#include "vtkIdList.h"
+#include "vtkIdTypeArray.h"
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMergeCells.h"
+#include "vtkMergePoints.h"
+#include "vtkMPICommunicator.h"
+#include "vtkMultiProcessController.h"
+#include "vtkNew.h"
+#include "vtkObjectFactory.h"
+#include "vtkPointData.h"
+#include "vtkPoints.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkUnstructuredGrid.h"
+
+#include <map>
+#include <set>
+#include <vector>
+
+//----------------------------------------------------------------------------
+// Helpers
+namespace
+{
+template<class T>
+bool AllGatherV(vtkMultiProcessController* controller,
+                const T* localV,
+                vtkIdType localSize,
+                std::vector<T>& globalV,
+                std::vector<vtkIdType>& sizes,
+                std::vector<vtkIdType>& offsets)
+{
+  int nbOfRanks = controller->GetNumberOfProcesses();
+  sizes.resize(nbOfRanks);
+  int ret = controller->AllGather(&localSize, &sizes[0], 1);
+  if (ret == 0)
+    {
+    vtkErrorWithObjectMacro(controller, << "Communication error!");
+    return false;
+    }
+  vtkIdType count = 0;
+  offsets.resize(nbOfRanks);
+  for (int i = 0; i < nbOfRanks; i++)
+    {
+    offsets[i] = count;
+    count += sizes[i];
+    }
+  globalV.resize(count);
+  if (count > 0)
+    {
+    controller->AllGatherV(localSize > 0 ? localV : 0,
+      &globalV[0], localSize, &sizes[0], &offsets[0]);
+    }
+  return true;
+}
+}
+
+//----------------------------------------------------------------------------
+// Internal data structures
+
+// Class to hold asynchronous communication information
+class CommDataInfo
+{
+public:
+  CommDataInfo() : SendLen(-1), RecvLen(-1), CommStep(0)
+  {
+    this->SendBuffer = vtkCharArray::New();
+    this->RecvBuffer = vtkCharArray::New();
+  }
+
+  CommDataInfo(const CommDataInfo& c)
+  {
+    *this = c;
+    if (this->SendBuffer) { this->SendBuffer->Register(0); }
+    if (this->RecvBuffer) { this->RecvBuffer->Register(0); }
+  }
+
+  ~CommDataInfo()
+  {
+    if (this->SendBuffer) { this->SendBuffer->Delete(); }
+    if (this->RecvBuffer) { this->RecvBuffer->Delete(); }
+  }
+
+  vtkMPICommunicator::Request SendReqs[2];
+  vtkMPICommunicator::Request RecvReqs[2];
+  vtkCharArray *SendBuffer;
+  vtkCharArray *RecvBuffer;
+  vtkIdType SendLen;
+  vtkIdType RecvLen;
+  int CommStep;
+};
+
+// Communication arrays
+struct vtkPUnstructuredGridGhostCellsGenerator::vtkInternals
+{
+  // For global ids
+  std::map<vtkIdType, vtkIdType> GlobalToLocalPointIdMap;
+  std::vector<vtkIdType> AllGlobalIdsOfSurfacePoints;
+
+  // For point coordinates
+  vtkNew<vtkMergePoints> LocalPoints;
+  std::vector<vtkIdType> LocalPointsMap;
+  std::vector<double> AllPointsOfSurfacePoints;
+
+  std::vector<vtkIdType> AllSizes;
+  std::vector<vtkIdType> AllOffsets;
+  std::map<int, std::set<vtkIdType> > NeighborRanksCells;
+  std::map<int, CommDataInfo> CommData;
+  vtkUnstructuredGridBase* Input;
+
+  vtkDataArray* InputGlobalPointIds;
+  bool UseGlobalPointIds;
+};
+
+static const int UGGCG_SIZE_EXCHANGE_TAG = 9000;
+static const int UGGCG_DATA_EXCHANGE_TAG = 9001;
+static const char* UGGCG_GLOBAL_POINT_IDS = "GlobalNodeIds";
+
+//----------------------------------------------------------------------------
+
+vtkStandardNewMacro(vtkPUnstructuredGridGhostCellsGenerator)
+vtkSetObjectImplementationMacro(
+  vtkPUnstructuredGridGhostCellsGenerator, Controller, vtkMultiProcessController);
+
+//----------------------------------------------------------------------------
+vtkPUnstructuredGridGhostCellsGenerator::vtkPUnstructuredGridGhostCellsGenerator()
+{
+  this->Controller = NULL;
+  this->SetController(vtkMultiProcessController::GetGlobalController());
+
+  this->Internals = NULL;
+  this->GlobalPointIdsArrayName = NULL;
+  this->UseGlobalPointIds = true;
+  this->SetGlobalPointIdsArrayName(UGGCG_GLOBAL_POINT_IDS);
+}
+
+//----------------------------------------------------------------------------
+vtkPUnstructuredGridGhostCellsGenerator::~vtkPUnstructuredGridGhostCellsGenerator()
+{
+  this->SetController(NULL);
+  this->SetGlobalPointIdsArrayName(NULL);
+
+  delete this->Internals;
+  this->Internals = 0;
+}
+
+//-----------------------------------------------------------------------------
+void vtkPUnstructuredGridGhostCellsGenerator::PrintSelf(ostream& os, vtkIndent indent)
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+//-----------------------------------------------------------------------------
+int vtkPUnstructuredGridGhostCellsGenerator::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output. Input may just have the UnstructuredGridBase
+  // interface, but output should be an unstructured grid.
+  vtkUnstructuredGridBase *input = vtkUnstructuredGridBase::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  int ghostLevels = 1;
+  //ghostLevels = outInfo->Get(
+  //  vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS());
+
+  if (!this->Controller)
+    {
+    this->Controller = vtkMultiProcessController::GetGlobalController();
+    }
+  output->Reset();
+
+  this->NumRanks = this->Controller ? this->Controller->GetNumberOfProcesses() : 1;
+  this->RankId = this->Controller ? this->Controller->GetLocalProcessId() : 0;
+  if (ghostLevels == 0 || !this->Controller || this->NumRanks == 1)
+    {
+    // Ghost levels are not requested. Nothing to do but pass the dataset.
+    if (this->RankId == 0)
+      {
+      vtkWarningMacro(<< "Ghost cells not requested or not needed.");
+      }
+    output->ShallowCopy(input);
+    return 1;
+    }
+
+  delete this->Internals;
+  this->Internals = new vtkPUnstructuredGridGhostCellsGenerator::vtkInternals();
+  this->Internals->Input = input;
+
+  vtkPointData *inputPD = input->GetPointData();
+  this->Internals->InputGlobalPointIds = inputPD->GetGlobalIds();
+
+  if (!this->Internals->InputGlobalPointIds)
+    {
+    this->Internals->InputGlobalPointIds =
+      inputPD->GetArray(this->GlobalPointIdsArrayName);
+    inputPD->SetGlobalIds(this->Internals->InputGlobalPointIds);
+    }
+
+  if (!this->UseGlobalPointIds)
+    {
+    this->Internals->InputGlobalPointIds = NULL;
+    }
+
+  this->ExtractAndReduceSurfacePoints();
+  this->UpdateProgress(0.3);
+
+  this->ComputeSharedPoints();
+  this->UpdateProgress(0.6);
+
+  this->ExtractAndSendGhostCells();
+  this->UpdateProgress(0.8);
+
+  this->ReceiveAndMergeGhostCells(output);
+  this->UpdateProgress(1.0);
+
+  output->GetInformation()->Set(vtkDataObject::DATA_NUMBER_OF_GHOST_LEVELS(), 1);
+
+  this->Controller->Barrier();
+
+  delete this->Internals;
+  this->Internals = 0;
+
+  return 1;
+}
+
+//-----------------------------------------------------------------------------
+// Step 1: Extract surface geometry and all reduce global ids of surface points
+void vtkPUnstructuredGridGhostCellsGenerator::ExtractAndReduceSurfacePoints()
+{
+  // Extract boundary cells and points with the surface filter
+  vtkNew<vtkDataSetSurfaceFilter> surfaceFilter;
+  surfaceFilter->SetInputData(this->Internals->Input);
+  surfaceFilter->PassThroughPointIdsOn();
+  surfaceFilter->Update();
+
+  vtkPolyData* surface = surfaceFilter->GetOutput();
+  vtkIdType nbSurfacePoints = surface->GetNumberOfPoints();
+  vtkCellArray* surfaceCells = surface->GetPolys();
+  surfaceCells->InitTraversal();
+  vtkIdType npts, *pts;
+
+  vtkIdTypeArray* surfaceOriginalPointIds = vtkIdTypeArray::SafeDownCast(
+    surface->GetPointData()->GetArray(surfaceFilter->GetOriginalPointIdsName()));
+
+  if (this->Internals->InputGlobalPointIds)
+    {
+    std::vector<vtkIdType> globalIdsOfSurfacePoints;
+    globalIdsOfSurfacePoints.reserve(nbSurfacePoints);
+
+    // Browse surface cells and save global and local ids of cell points
+    while (surfaceCells->GetNextCell(npts, pts))
+      {
+      for (vtkIdType i = 0; i < npts; i++)
+        {
+        vtkIdType origPtId = surfaceOriginalPointIds->GetValue(pts[i]);
+        vtkIdType globalPtId = static_cast<vtkIdType>(
+          this->Internals->InputGlobalPointIds->GetTuple1(origPtId));
+
+        if (this->Internals->GlobalToLocalPointIdMap.find(globalPtId) ==
+          this->Internals->GlobalToLocalPointIdMap.end())
+          {
+          this->Internals->GlobalToLocalPointIdMap[globalPtId] = origPtId;
+          globalIdsOfSurfacePoints.push_back(globalPtId);
+          }
+        }
+      }
+
+    // Now reduce surface point global ids on ALL ranks
+    ::AllGatherV(this->Controller, &globalIdsOfSurfacePoints[0],
+      globalIdsOfSurfacePoints.size(),
+      this->Internals->AllGlobalIdsOfSurfacePoints,
+      this->Internals->AllSizes, this->Internals->AllOffsets);
+    }
+  else
+    {
+    // We can't use global ids, so we will process point coordinates instead
+    vtkPoints* inputPoints = this->Internals->Input->GetPoints();
+    vtkNew<vtkPoints> surfacePoints;
+    surfacePoints->SetDataTypeToDouble();
+    surfacePoints->Allocate(nbSurfacePoints);
+    this->Internals->LocalPoints->InitPointInsertion(
+      surfacePoints.Get(), surface->GetPoints()->GetBounds());
+    this->Internals->LocalPointsMap.reserve(nbSurfacePoints);
+
+    // Browse surface cells and push point coordinates to the locator
+    while (surfaceCells->GetNextCell(npts, pts))
+      {
+      for (vtkIdType i = 0; i < npts; i++)
+        {
+        vtkIdType origPtId = surfaceOriginalPointIds->GetValue(pts[i]);
+        double p[3];
+        inputPoints->GetPoint(origPtId, p);
+        vtkIdType sid;
+        if (this->Internals->LocalPoints->InsertUniquePoint(p, sid))
+          {
+          // New point, save the id of the original grid point id associated
+          // to this surface point
+          if (static_cast<vtkIdType>(this->Internals->LocalPointsMap.size()) <= sid)
+            {
+            this->Internals->LocalPointsMap.resize(sid + 1);
+            }
+          this->Internals->LocalPointsMap[sid] = origPtId;
+          }
+        }
+      }
+
+    // Now reduce surface point coordinates on ALL ranks
+    ::AllGatherV(this->Controller,
+      (double*)surfacePoints->GetVoidPointer(0),
+      surfacePoints->GetNumberOfPoints() * 3,
+      this->Internals->AllPointsOfSurfacePoints,
+      this->Internals->AllSizes, this->Internals->AllOffsets);
+    }
+}
+
+//---------------------------------------------------------------------------
+// Step 2: browse global ids/point coordinates of other ranks and check if some
+// are duplicated locally.
+// For each neighbor rank, save the ids of the cells adjacent to the surface
+// points shared, those cells are the ghost cells we will send them.
+void vtkPUnstructuredGridGhostCellsGenerator::ComputeSharedPoints()
+{
+  vtkNew<vtkIdList> cellIdsList;
+  for (int i = 0; i < this->NumRanks; i++)
+    {
+    if (i == this->RankId)
+      {
+      continue;
+      }
+    for (vtkIdType j = 0, idx = this->Internals->AllOffsets[i];
+         j < this->Internals->AllSizes[i]; j++, idx++)
+      {
+      vtkIdType localPointId = -1;
+      if (this->Internals->InputGlobalPointIds)
+        {
+        // Check if this point exists locally from its global ids, if so
+        // get its local id.
+        vtkIdType gid = this->Internals->AllGlobalIdsOfSurfacePoints[idx];
+        std::map<vtkIdType, vtkIdType>::iterator iter =
+          this->Internals->GlobalToLocalPointIdMap.find(gid);
+        if (iter != this->Internals->GlobalToLocalPointIdMap.end())
+          {
+          localPointId = iter->second;
+          }
+        }
+      else
+        {
+        // Check if this point exists locally from its coordinates, if so
+        // get its local id.
+        double *p = &this->Internals->AllPointsOfSurfacePoints[idx];
+        localPointId = this->Internals->LocalPoints->IsInsertedPoint(p);
+
+        if (localPointId != -1)
+          {
+          localPointId = this->Internals->LocalPointsMap[localPointId];
+          }
+        idx += 2; // jump to next coordinates
+        j += 2;
+        }
+
+      if (localPointId != -1)
+        {
+        // Current rank also has a copy of this global point
+        cellIdsList->Reset();
+        // Get the cells connected to this point
+        this->Internals->Input->GetPointCells(localPointId, cellIdsList.Get());
+        vtkIdType nbIds = cellIdsList->GetNumberOfIds();
+        // Add those cells to the list of cells to send to this rank
+        for (vtkIdType k = 0; k < nbIds; k++)
+          {
+          this->Internals->NeighborRanksCells[i].insert(cellIdsList->GetId(k));
+          }
+        }
+      }
+    }
+
+  // Release memory of all reduced arrays
+  this->Internals->AllGlobalIdsOfSurfacePoints.resize(0);
+  this->Internals->AllPointsOfSurfacePoints.resize(0);
+  this->Internals->AllSizes.resize(0);
+  this->Internals->AllOffsets.resize(0);
+  // Now we know our neighbors and which points we have in common and the
+  // ghost cells to share.
+}
+
+//-----------------------------------------------------------------------------
+// Step 3: extract and send the ghost cells to the neighbor ranks
+void vtkPUnstructuredGridGhostCellsGenerator::ExtractAndSendGhostCells()
+{
+  vtkNew<vtkIdList> cellIdsList;
+  vtkNew<vtkExtractCells> extractCells;
+  extractCells->SetInputData(this->Internals->Input);
+  std::map<int, std::set<vtkIdType> >::iterator iter =
+    this->Internals->NeighborRanksCells.begin();
+
+  vtkMPICommunicator* com =
+    vtkMPICommunicator::SafeDownCast(this->Controller->GetCommunicator());
+
+  // Browse all neighbor ranks and extract the cells connected to the points we share
+  for (; iter != this->Internals->NeighborRanksCells.end(); ++iter)
+    {
+    int toRank = iter->first;
+    std::set<vtkIdType>& cellsToShare = iter->second;
+    cellIdsList->SetNumberOfIds(cellsToShare.size());
+    std::set<vtkIdType>::iterator sIter = cellsToShare.begin();
+    for (vtkIdType i = 0; sIter != cellsToShare.end(); ++sIter, i++)
+      {
+      cellIdsList->SetId(i, *sIter);
+      }
+    extractCells->SetCellList(cellIdsList.Get());
+    extractCells->Update();
+    vtkUnstructuredGrid* extractGrid = extractCells->GetOutput();
+
+    // Send the extracted grid to the neighbor rank asynchronously
+    CommDataInfo& c = this->Internals->CommData[toRank];
+    if (vtkCommunicator::MarshalDataObject(extractGrid, c.SendBuffer))
+      {
+      c.SendLen = c.SendBuffer->GetNumberOfTuples();
+      // Send data length
+      com->NoBlockSend(&c.SendLen, 1, toRank, UGGCG_SIZE_EXCHANGE_TAG, c.SendReqs[0]);
+      // Send raw data
+      com->NoBlockSend((char*)c.SendBuffer->GetVoidPointer(0), c.SendLen, toRank,
+        UGGCG_DATA_EXCHANGE_TAG, c.SendReqs[1]);
+      }
+    }
+}
+
+//-----------------------------------------------------------------------------
+// Step 4: receive the ghost cells from the neighbor ranks and merge them
+// to the local grid.
+void vtkPUnstructuredGridGhostCellsGenerator::ReceiveAndMergeGhostCells(
+  vtkUnstructuredGrid *output)
+{
+  // We need to compute a rough estimation of the total number of cells and
+  // points for vtkMergeCells
+  vtkIdType totalNbCells = this->Internals->Input->GetNumberOfCells();
+  vtkIdType totalNbPoints = this->Internals->Input->GetNumberOfPoints();
+
+  vtkMPICommunicator* com =
+    vtkMPICommunicator::SafeDownCast(this->Controller->GetCommunicator());
+
+  // Browse all neighbor ranks and receive the mesh that contains cells
+  int nbNeighbors = static_cast<int>(this->Internals->NeighborRanksCells.size());
+  std::vector<vtkUnstructuredGridBase*> neighborGrids;
+  neighborGrids.reserve(nbNeighbors);
+
+  // First create requests to receive the size of the mesh to receive
+  std::map<int, std::set<vtkIdType> >::iterator iter;
+  for (iter = this->Internals->NeighborRanksCells.begin();
+    iter != this->Internals->NeighborRanksCells.end(); ++iter)
+    {
+    vtkIdType fromRank = iter->first;
+    CommDataInfo& c = this->Internals->CommData[fromRank];
+    com->NoBlockReceive(
+      &c.RecvLen, 1, fromRank, UGGCG_SIZE_EXCHANGE_TAG, c.RecvReqs[0]);
+    }
+
+  // Then, once the data length is received, create requests to receive the mesh data
+  int counter = 0;
+  while (counter != nbNeighbors)
+    {
+    for (iter = this->Internals->NeighborRanksCells.begin();
+      iter != this->Internals->NeighborRanksCells.end(); ++iter)
+      {
+      vtkIdType fromRank = iter->first;
+      CommDataInfo& c = this->Internals->CommData[fromRank];
+      if (!c.RecvReqs[0].Test() || c.CommStep != 0)
+        {
+        continue;
+        }
+      c.CommStep = 1;
+      c.RecvBuffer->SetNumberOfValues(c.RecvLen);
+      com->NoBlockReceive(
+        (char*)c.RecvBuffer->GetVoidPointer(0), c.RecvLen, fromRank,
+        UGGCG_DATA_EXCHANGE_TAG, c.RecvReqs[1]);
+      counter++;
+      }
+    }
+
+  // Browse all neighbor ranks and receive the mesh that contains cells
+  // that are ghost cells for current rank.
+  counter = 0;
+  while (counter != nbNeighbors)
+    {
+    for (iter = this->Internals->NeighborRanksCells.begin();
+    iter != this->Internals->NeighborRanksCells.end(); ++iter)
+      {
+      vtkIdType fromRank = iter->first;
+      CommDataInfo& c = this->Internals->CommData[fromRank];
+
+      if (!c.RecvReqs[1].Test() || c.CommStep != 1)
+        {
+        continue;
+        }
+
+      c.CommStep = 2;
+      vtkUnstructuredGrid* grid = vtkUnstructuredGrid::New();
+      vtkCommunicator::UnMarshalDataObject(c.RecvBuffer, grid);
+      c.RecvBuffer->Delete();
+      c.RecvBuffer = NULL;
+
+      // Flag the received grid elements as ghosts
+      grid->AllocatePointGhostArray();
+      grid->AllocateCellGhostArray();
+      grid->GetPointGhostArray()->FillComponent(0, 1);
+      grid->GetCellGhostArray()->FillComponent(0, 1);
+
+      // Make sure the global point ids array is tagged accordingly
+      if (this->Internals->InputGlobalPointIds &&
+          !grid->GetPointData()->GetGlobalIds())
+        {
+        grid->GetPointData()->SetGlobalIds(grid->GetPointData()->GetArray(
+          this->Internals->InputGlobalPointIds->GetName()));
+        }
+
+      totalNbCells += grid->GetNumberOfCells();
+      totalNbPoints += grid->GetNumberOfPoints();
+
+      neighborGrids.push_back(grid);
+
+      counter++;
+      }
+    }
+
+  // Shallow copy the input grid and initialize the ghost arrays
+  vtkNew<vtkUnstructuredGrid> inputCopy;
+  inputCopy->ShallowCopy(this->Internals->Input);
+  inputCopy->AllocatePointGhostArray();
+  inputCopy->AllocateCellGhostArray();
+
+  // MergeCells merge input + grids that contains ghost cells to the output grid
+  vtkNew<vtkMergeCells> mergeCells;
+  mergeCells->SetUnstructuredGrid(output);
+  mergeCells->SetTotalNumberOfCells(totalNbCells);
+  mergeCells->SetTotalNumberOfPoints(totalNbPoints);
+  mergeCells->SetTotalNumberOfDataSets(
+    1 + static_cast<int>(this->Internals->NeighborRanksCells.size()));
+  mergeCells->SetUseGlobalIds(this->Internals->InputGlobalPointIds != 0 ? 1 : 0);
+  mergeCells->SetPointMergeTolerance(0.0);
+
+  // Merge input grid first
+  mergeCells->MergeDataSet(inputCopy.Get());
+
+  // Then merge ghost grid from neighbor rank
+  for (std::size_t i = 0; i < neighborGrids.size(); i++)
+    {
+    mergeCells->MergeDataSet(neighborGrids[i]);
+    neighborGrids[i]->Delete();
+    }
+
+  // Finalize the merged output
+  mergeCells->Finish();
+}
diff --git a/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.h b/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.h
new file mode 100644 (file)
index 0000000..8102d82
--- /dev/null
@@ -0,0 +1,104 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPUnstructuredGridGhostCellsGenerator.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// .NAME vtkPUnstructuredGridGhostCellsGenerator - Builds ghost cells for a
+//  distributed unstructured grid dataset.
+//
+// .SECTION Description
+// This filter generate ghost cells for distributed a unstructured grid in
+// parallel - using MPI asynchronous communcations.
+// The filter can take benefit of the input grid point global ids to perform.
+//
+// .SECTION Caveats
+//  <ul>
+//    <li> A step of 'all reduce' (each processor send/receive data to/from
+//         all other processors.
+//    <li> The code currently assumes one grid per rank. </li>
+//    <li> PointData and CellData must match across partitions/processes. </li>
+//  </ul>
+//
+// .SECTION See Also
+// vtkDistributedDataFilter vtkPUnstructuredGridGhostDataGenerator
+//
+// .SECTION Thanks
+// This filter has been developed by Joachim Pouderoux, Kitware SAS 2015.
+
+#ifndef vtkPUnstructuredGridGhostCellsGenerator_h
+#define vtkPUnstructuredGridGhostCellsGenerator_h
+
+#include "vtkUnstructuredGridAlgorithm.h"
+
+class vtkMultiProcessController;
+class vtkUnstructuredGrid;
+
+class vtkPUnstructuredGridGhostCellsGenerator:
+  public vtkUnstructuredGridAlgorithm
+{
+  vtkTypeMacro(vtkPUnstructuredGridGhostCellsGenerator, vtkUnstructuredGridAlgorithm);
+
+public:
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  static vtkPUnstructuredGridGhostCellsGenerator *New();
+
+  // Description:
+  // Set/Get the MPI multi process controller object.
+  void SetController(vtkMultiProcessController *c);
+  vtkGetObjectMacro(Controller, vtkMultiProcessController);
+
+  // Description:
+  // Specify if the filter must take benefit of global point ids if they exist.
+  // If false, point coordinates are used. Default is TRUE.
+  vtkSetMacro(UseGlobalPointIds, bool);
+  vtkGetMacro(UseGlobalPointIds, bool);
+  vtkBooleanMacro(UseGlobalPointIds, bool);
+
+  // Description:
+  // Specify the name of the global point ids data array if the GlobalIds
+  // attribute array is not set. Default is "GlobalNodeIds".
+  vtkSetStringMacro(GlobalPointIdsArrayName);
+  vtkGetStringMacro(GlobalPointIdsArrayName);
+
+protected:
+  vtkPUnstructuredGridGhostCellsGenerator();
+  ~vtkPUnstructuredGridGhostCellsGenerator();
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+
+  void ExtractAndReduceSurfacePoints();
+
+  void ComputeSharedPoints();
+
+  void ExtractAndSendGhostCells();
+
+  void ReceiveAndMergeGhostCells(vtkUnstructuredGrid*);
+
+  vtkMultiProcessController *Controller;
+
+  int NumRanks;
+  int RankId;
+  char* GlobalPointIdsArrayName;
+  bool UseGlobalPointIds;
+
+private:
+  struct vtkInternals;
+  vtkInternals* Internals;
+
+  vtkPUnstructuredGridGhostCellsGenerator(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented
+  void operator=(const vtkPUnstructuredGridGhostCellsGenerator&); // Not implemented
+};
+
+#endif
diff --git a/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.cxx b/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.cxx
new file mode 100644 (file)
index 0000000..b47aad6
--- /dev/null
@@ -0,0 +1,91 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPVUnstructuredGridGhostCellsGenerator.cxx
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+#include "vtkPVUnstructuredGridGhostCellsGenerator.h"
+#include "vtkPVConfig.h" // need ParaView defines before MPI stuff
+
+#include "vtkInformation.h"
+#include "vtkInformationVector.h"
+#include "vtkMultiProcessController.h"
+#include "vtkNew.h"
+#include "vtkObjectFactory.h"
+#include "vtkStreamingDemandDrivenPipeline.h"
+#include "vtkUnstructuredGrid.h"
+
+#ifdef PARAVIEW_USE_MPI
+#  include "vtkPUnstructuredGridGhostCellsGenerator.h"
+#endif
+
+static const char* PVUGGCG_GLOBAL_POINT_IDS = "GlobalNodeIds";
+
+//----------------------------------------------------------------------------
+
+vtkStandardNewMacro(vtkPVUnstructuredGridGhostCellsGenerator)
+vtkSetObjectImplementationMacro(
+  vtkPVUnstructuredGridGhostCellsGenerator, Controller, vtkMultiProcessController);
+
+//----------------------------------------------------------------------------
+vtkPVUnstructuredGridGhostCellsGenerator::vtkPVUnstructuredGridGhostCellsGenerator()
+{
+  this->Controller = NULL;
+  this->SetController(vtkMultiProcessController::GetGlobalController());
+
+  this->GlobalPointIdsArrayName = NULL;
+  this->UseGlobalPointIds = true;
+  this->SetGlobalPointIdsArrayName(PVUGGCG_GLOBAL_POINT_IDS);
+}
+
+//----------------------------------------------------------------------------
+vtkPVUnstructuredGridGhostCellsGenerator::~vtkPVUnstructuredGridGhostCellsGenerator()
+{
+  this->SetController(NULL);
+  this->SetGlobalPointIdsArrayName(NULL);
+}
+
+//-----------------------------------------------------------------------------
+void vtkPVUnstructuredGridGhostCellsGenerator::PrintSelf(ostream& os, vtkIndent indent)
+{
+  Superclass::PrintSelf(os, indent);
+}
+
+//-----------------------------------------------------------------------------
+int vtkPVUnstructuredGridGhostCellsGenerator::RequestData(
+  vtkInformation *vtkNotUsed(request),
+  vtkInformationVector **inputVector,
+  vtkInformationVector *outputVector)
+{
+  // get the info objects
+  vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
+  vtkInformation *outInfo = outputVector->GetInformationObject(0);
+
+  // get the input and output. Input may just have the UnstructuredGridBase
+  // interface, but output should be an unstructured grid.
+  vtkUnstructuredGridBase *input = vtkUnstructuredGridBase::SafeDownCast(
+    inInfo->Get(vtkDataObject::DATA_OBJECT()));
+  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
+    outInfo->Get(vtkDataObject::DATA_OBJECT()));
+#ifdef PARAVIEW_USE_MPI
+  vtkNew<vtkPUnstructuredGridGhostCellsGenerator> ghostGenerator;
+  ghostGenerator->SetInputData(input);
+  ghostGenerator->SetController(this->Controller);
+  ghostGenerator->SetUseGlobalPointIds(this->UseGlobalPointIds);
+  ghostGenerator->SetGlobalPointIdsArrayName(this->GlobalPointIdsArrayName);
+  ghostGenerator->Update();
+  output->ShallowCopy(ghostGenerator->GetOutput());
+#else
+  output->ShallowCopy(input);
+#endif
+  return 1;
+}
diff --git a/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.h b/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.h
new file mode 100644 (file)
index 0000000..9ad1b20
--- /dev/null
@@ -0,0 +1,91 @@
+/*=========================================================================
+
+  Program:   Visualization Toolkit
+  Module:    vtkPVUnstructuredGridGhostCellsGenerator.h
+
+  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
+  All rights reserved.
+  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
+
+     This software is distributed WITHOUT ANY WARRANTY; without even
+     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
+     PURPOSE.  See the above copyright notice for more information.
+
+=========================================================================*/
+
+// .NAME vtkPVUnstructuredGridGhostCellsGenerator - Builds ghost cells for a
+//  distributed unstructured grid dataset.
+//
+// .SECTION Description
+// This filter generate ghost cells for distributed a unstructured grid in
+// parallel - using MPI asynchronous communcations.
+// The filter can take benefit of the input grid point global ids to perform.
+//
+// .SECTION Caveats
+//  <ul>
+//    <li> A step of 'all reduce' (each processor send/receive data to/from
+//         all other processors.
+//    <li> The code currently assumes one grid per rank. </li>
+//    <li> PointData and CellData must match across partitions/processes. </li>
+//  </ul>
+//
+// .SECTION See Also
+// vtkDistributedDataFilter vtkPUnstructuredGridGhostDataGenerator
+//
+// .SECTION Thanks
+// This filter has been developed by Joachim Pouderoux, Kitware SAS 2015.
+
+#ifndef vtkPVUnstructuredGridGhostCellsGenerator_h
+#define vtkPVUnstructuredGridGhostCellsGenerator_h
+
+#include "vtkUnstructuredGridAlgorithm.h"
+
+class vtkMultiProcessController;
+class vtkUnstructuredGrid;
+
+class vtkPVUnstructuredGridGhostCellsGenerator:
+  public vtkUnstructuredGridAlgorithm
+{
+  vtkTypeMacro(vtkPVUnstructuredGridGhostCellsGenerator, vtkUnstructuredGridAlgorithm);
+
+public:
+  void PrintSelf(ostream& os, vtkIndent indent);
+
+  static vtkPVUnstructuredGridGhostCellsGenerator *New();
+
+  // Description:
+  // Set/Get the MPI multi process controller object.
+  void SetController(vtkMultiProcessController *c);
+  vtkGetObjectMacro(Controller, vtkMultiProcessController);
+
+  // Description:
+  // Specify if the filter must take benefit of global point ids if they exist.
+  // If false, point coordinates are used. Default is TRUE.
+  vtkSetMacro(UseGlobalPointIds, bool);
+  vtkGetMacro(UseGlobalPointIds, bool);
+  vtkBooleanMacro(UseGlobalPointIds, bool);
+
+  // Description:
+  // Specify the name of the global point ids data array if the GlobalIds
+  // attribute array is not set. Default is "GlobalNodeIds".
+  vtkSetStringMacro(GlobalPointIdsArrayName);
+  vtkGetStringMacro(GlobalPointIdsArrayName);
+
+protected:
+  vtkPVUnstructuredGridGhostCellsGenerator();
+  ~vtkPVUnstructuredGridGhostCellsGenerator();
+
+  virtual int RequestData(vtkInformation *, vtkInformationVector **,
+    vtkInformationVector *);
+
+  vtkMultiProcessController *Controller;
+  char* GlobalPointIdsArrayName;
+  bool UseGlobalPointIds;
+
+private:
+
+  vtkPVUnstructuredGridGhostCellsGenerator(const vtkPVUnstructuredGridGhostCellsGenerator&); // Not implemented
+  void operator=(const vtkPVUnstructuredGridGhostCellsGenerator&); // Not implemented
+};
+
+#endif
index 163fef3102a5fe1a8a0610c65a87ba624a3954dc..1f5aeb09643e47fce0fe6b9ede95e721dc901ed3 100644 (file)
@@ -31,9 +31,10 @@ INCLUDE(${PARAVIEW_USE_FILE})
 OPTION(BUILD_SHARED_LIBS "Build with shared libraries" ${VTK_BUILD_SHARED_LIBS})
 
 # Add subdirectories
-ADD_SUBDIRECTORY(JSONParser)
+# ADD_SUBDIRECTORY(JSONParser)
+#IF(SALOME_BUILD_TESTS)
+#  ENABLE_TESTING()
+#  ADD_SUBDIRECTORY(Test)
+#ENDIF()
+
 ADD_SUBDIRECTORY(ParaViewPlugin)
-IF(SALOME_BUILD_TESTS)
-  ENABLE_TESTING()
-  ADD_SUBDIRECTORY(Test)
-ENDIF()
\ No newline at end of file
index 6fd4e2c4e56ec978239b9a521ddc534c5010ddd9..eac829fae9f09ba0d42a3996e1e12a750f8b7338 100644 (file)
@@ -25,8 +25,6 @@ ADD_PARAVIEW_PLUGIN(JSONReader "1.0"
   SERVER_MANAGER_SOURCES vtkJSONReader.cxx
   REQUIRED_ON_SERVER)
 
-TARGET_LINK_LIBRARIES(JSONReader vtkJSONParser)
-
 INSTALL(TARGETS JSONReader
   DESTINATION lib/paraview
 )
index adec0627896d1bfe1b3a6c2924024cfc6ca596aa..cc1f67038b1be6185d54759d1bb27c574d43f868 100644 (file)
 // Author: Roman NIKOLAEV
 
 #include "vtkJSONReader.h"
-#include "vtkJSONParser.h"
 
 #include <vtkObjectFactory.h>
 #include <vtkTable.h>
 #include <vtkInformationVector.h>
 #include <vtkInformation.h>
 #include <vtkStreamingDemandDrivenPipeline.h>
+#include <vtkDoubleArray.h>
 #include <vtkVariantArray.h>
 #include <vtkStringArray.h>
 #include <vtkStringToNumeric.h>
+#include <vtkSetGet.h>
+#include <vtksys/RegularExpression.hxx>
 
 #include <stdexcept>
 #include <sstream>
 
+// Key words
+#define MD  "_metadata"
+#define CMT "_comment"
+#define TBN "table_name"
+#define TBD "table_description"
+#define SHT "short_names"
+#define LNG "long_names"
+#define UNT "units"
+#define DT "date"
+
+#define NA "n/a"
+
+// Exception
+//---------------------------------------------------
+vtkJSONException::vtkJSONException(const char *reason) : Reason(reason) {
+
+}
+
+//---------------------------------------------------
+vtkJSONException::~vtkJSONException() throw () {
+}
+
+//---------------------------------------------------
+const char* vtkJSONException::what() const throw() {
+  return Reason.c_str();
+}
+
+
+//---------------------------------------------------
+class Container {
+public:
+  typedef std::vector<std::pair<std::string,std::vector<double>>> DataType;
+  Container(){}
+  void initKeys(std::vector<std::string> &keys, std::string &err) {
+    for(int i = 0; i < keys.size(); i++) {
+      if( !checkVar(keys[i].c_str()) ) {
+       std::ostringstream oss;
+       oss<<"Bad key value '"<<keys[i].c_str()<<"'";
+       err = oss.str();
+       return;
+      }
+      _data.push_back(std::make_pair(keys[i],std::vector<double>()));
+    }
+  }
+
+  void addValue(std::string key, double value, std::string& err) {
+    if( !checkVar(key.c_str()) ) {
+      std::ostringstream oss;
+      oss<<"Bad key value '"<<key.c_str()<<"'";
+      err = oss.str();
+      return;
+    }
+    bool found = false;
+    for(int i = 0; i < _data.size(); i++) {
+      if(_data[i].first == key) {
+       _data[i].second.push_back(value);
+       found = true;
+       break;
+      }
+    }
+    if(!found) {
+      std::ostringstream oss;
+      oss<<"Bad key value '"<<key<<"'";
+      err = oss.str();
+    }
+  }
+  
+  DataType& getData() {
+    return _data;
+  }
+private:
+  bool checkVar(const char* var) {
+    vtksys::RegularExpression regEx("^[a-zA-Z_][a-zA-Z0-9_]*$");
+    return regEx.find(var);
+  }
+private:
+  DataType _data;
+};
+
 vtkStandardNewMacro(vtkJSONReader);
 
 //---------------------------------------------------
-vtkJSONReader::vtkJSONReader()
-{
+vtkJSONReader::vtkJSONReader() {
   this->SetNumberOfInputPorts(0);
   this->SetNumberOfOutputPorts(1);
   this->FileName = NULL;
-  this->Parser = vtkJSONParser::New();
 }
 
 //---------------------------------------------------
 vtkJSONReader::~vtkJSONReader()
 {
   this->SetFileName(NULL);
-  this->Parser->Delete();
-}
-
-//---------------------------------------------------
-int vtkJSONReader::CanReadFile(const char* fname)
-{
-  return 1;
 }
 
 //---------------------------------------------------
@@ -63,34 +135,260 @@ void vtkJSONReader::PrintSelf(ostream& os, vtkIndent indent)
   this->Superclass::PrintSelf(os, indent);
   os << indent << "FileName: " 
       << (this->FileName ? this->FileName : "(none)") << endl;
-  os << indent << "Parser: "<<this->Parser << endl;
 }
 
 //---------------------------------------------------
 int vtkJSONReader::RequestData(vtkInformation*, 
-    vtkInformationVector**,
-    vtkInformationVector* outputVector)
-{
+                              vtkInformationVector**,
+                              vtkInformationVector* outputVector) {
   vtkTable* const output_table = vtkTable::GetData(outputVector);
-
+  
   vtkInformation* const outInfo = outputVector->GetInformationObject(0);
   if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) &&
-  outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0)
-  {
-   return 1;
-  }
-
- // If the filename is not defined
- if (!this->FileName && !this->Parser)
-   {
-     return 1;
-   }
-
- this->Parser->SetFileName(this->FileName);
- try{
-   return this->Parser->Parse(output_table);
- } catch(vtkJSONException e) {
-   std::cout<<e.what()<<std::endl;
-   return 1;
- }
+     outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER()) > 0) {
+    return 0;
+  }
+  
+  Json::Value root;
+  int parseResult = 0;
+  parseResult = this->CanParseFile(this->FileName, root);
+  if(!parseResult)
+    return 0;
+
+  try {
+    return this->Parse(root, output_table);
+    return 1;
+  } 
+  catch(vtkJSONException e)  {
+    std::ostringstream oss;
+    oss<<e.what();
+    if(this->HasObserver("ErrorEvent") )
+      {
+       this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+      }
+    else
+      {
+       vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str())); 
+       vtkObject::BreakOnError();
+      }
+    return 0;
+  }
+}
+
+//---------------------------------------------------
+int vtkJSONReader::CanParseFile(const char *fname, Json::Value &root)
+{
+  if ( !fname) {
+    vtkErrorMacro(<< "Input file name is not specified !!! ");
+    return 0;
+  }
+
+  ifstream file;
+  std::ostringstream oss;
+  bool parsedSuccess = true;
+  Json::Reader reader;
+
+  file.open(fname);
+  if ( !file.is_open() ) {
+      oss<< "Unable to open file: " << this->FileName;
+      parsedSuccess = false;
+  } else {
+    parsedSuccess = reader.parse(file, root, false);
+    file.close();    
+  }
+  if ( !parsedSuccess ) {
+    if(oss.str().empty()) {
+      oss<<"Failed to parse JSON file: " << "\n" << reader.getFormattedErrorMessages();
+    }
+    if(this->HasObserver("ErrorEvent") ) {
+      this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+    }
+    else {
+      vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str())); 
+      vtkObject::BreakOnError();
+    }
+    return 0;
+  }
+  return 1;
+}
+
+//---------------------------------------------------
+int vtkJSONReader::Parse(Json::Value& root, vtkTable *table) {
+  bool hasShortNames = false;
+  bool hasUnits = false;
+  Container container;
+
+
+  Json::Value jSONListOfNames;
+  Json::Value jSONListOfUnits;
+  Json::Value jSONTableName;
+  std::vector<std::string> short_names;
+
+  if ( root.isMember(MD) ) {
+    Json::Value jSONMetaData = root.get(MD, Json::Value::null);
+
+    if ( jSONMetaData.isMember(CMT) ) {
+      Json::Value jSONComment = jSONMetaData.get(CMT, Json::Value::null);
+      vtkDebugMacro(<<"Table Comment  : " << jSONComment.asString());
+    }
+    if ( jSONMetaData.isMember(TBN) ) {
+      jSONTableName = jSONMetaData.get(TBN, Json::Value::null);      
+      vtkDebugMacro(<<"Table Name  : " << jSONTableName.asString());
+    }
+
+    if ( jSONMetaData.isMember(TBD) ) {
+      Json::Value jSONTableDescription = jSONMetaData.get(TBD, Json::Value::null);
+      vtkDebugMacro(<<"Table Description  : "  << jSONTableDescription.asString());
+    }
+
+    if ( jSONMetaData.isMember(DT) ) {
+      Json::Value jSONDate = jSONMetaData.get("date", Json::Value::null);
+      vtkDebugMacro(<<"Date  : " << jSONDate.asString());
+    }
+
+    if ( jSONMetaData.isMember(SHT) ) {
+      hasShortNames = true;
+      jSONListOfNames = jSONMetaData.get(SHT, Json::Value::null);
+      std::ostringstream oss;
+      oss<< "Short Names : [ ";
+      for (int i = 0; i < jSONListOfNames.size(); i++) {
+        oss << "'" << jSONListOfNames[i].asString() << "'";
+       short_names.push_back(jSONListOfNames[i].asString());
+        if ( i != jSONListOfNames.size() - 1 ) {
+          oss << ", ";
+        }
+      }
+      oss << " ]";
+      vtkDebugMacro(<<oss.str().c_str());
+    }
+
+    Json::Value jSONListOfLongName;
+    if ( jSONMetaData.isMember(LNG) ) {
+      jSONListOfLongName = jSONMetaData.get(LNG, Json::Value::null);
+      std::ostringstream oss;
+      oss << "Long Names : [ ";
+      for (int i = 0; i < jSONListOfLongName.size(); ++i) {
+        oss << "'" << jSONListOfLongName[i].asString() << "'";
+        if ( i != jSONListOfLongName.size()-1 ) {
+          oss << ", ";
+        }
+      }
+      oss<<" ]";
+      vtkDebugMacro(<<oss.str().c_str());
+    }
+    if ( jSONMetaData.isMember(UNT) ) {
+      jSONListOfUnits = jSONMetaData.get(UNT, Json::Value::null);
+      hasUnits = true;
+      std::ostringstream oss;
+      oss << "Units : [ ";
+      for (int i = 0; i < jSONListOfUnits.size(); ++i) {
+        oss << "'" << jSONListOfUnits[i].asString() << "'";
+        if ( i != jSONListOfUnits.size()-1 ) {
+          oss << ", ";
+        }
+      }
+      oss << " ]";
+      vtkDebugMacro(<<oss.str().c_str());
+    }
+    root.removeMember(MD);
+  }
+
+  Json::Value::iterator it = root.begin();
+  Json::Value newRoot = Json::Value::null;
+  
+  int nbElems=0;
+  bool hasArray = false;
+  for( ; it != root.end(); it++) {
+    nbElems++;
+    if((*it).type() == Json::arrayValue) {
+      newRoot = (*it);
+      hasArray = true;
+    }
+  }
+  if(hasArray && nbElems > 1) {
+    throw vtkJSONException("Wrong JSON file: it contains array and others elements");
+  }
+
+  if(newRoot == Json::Value::null) {
+    newRoot = root;
+  }
+    
+  it = newRoot.begin();
+  bool initContainer = false;
+  for( ; it != newRoot.end(); it++) {
+    if((*it).type() != Json::objectValue) {
+      std::ostringstream oss;
+      oss<<"Wrong JSON file: unexpected element, named '"<<(it.name())<<"'";
+      throw vtkJSONException(oss.str().c_str());
+    }
+    Json::Value::Members members = (*it).getMemberNames();    
+    if(!initContainer) {
+      if(!hasShortNames) {
+       short_names = members;
+      }
+      std::string err;
+      container.initKeys(short_names,err);
+      if(!err.empty()){
+       throw vtkJSONException(err.c_str());
+      }
+      initContainer = true;
+    }
+    for(int i=0; i < members.size(); i++) { 
+      Json::Value val = (*it).get(members[i],Json::Value::null);
+      double value = 0.0;
+      switch (val.type()) {    
+          case Json::stringValue: {
+            std::string s("Item with name '");
+            s += it.name();
+            s += "' has key '";
+            s += members[i];
+            s += "' with string value '";
+            s += val.asString();
+            s += "' ! Value set to 0.0";
+           if(this->HasObserver("WarningEvent") ) {
+             this->InvokeEvent("WarningEvent",const_cast<char *>(s.c_str()));
+           }
+           else {
+             vtkOutputWindowDisplayWarningText(const_cast<char *>(s.c_str())); 
+           }
+            break;
+         }
+          default:
+            value = val.asDouble();
+      }
+      std::string err;
+      container.addValue(members[i],value,err);
+      if(!err.empty()){
+       throw vtkJSONException(err.c_str());
+      }
+    }
+  }
+  
+  table->GetInformation()->Set(vtkDataObject::FIELD_NAME(), jSONTableName.asString().c_str());
+  Container::DataType data = container.getData();
+  if(hasUnits && data.size() != jSONListOfUnits.size()) {
+    throw vtkJSONException("W");
+  }
+  
+  int nbRows = 0;
+  if(data.size() > 0)
+    nbRows = data[0].second.size();
+
+  for(int i = 0; i < data.size(); i++) {
+    vtkDoubleArray* newCol = vtkDoubleArray::New();
+    newCol->SetNumberOfValues(nbRows);
+    std::string name = data[i].first;
+    name += "[";
+    if(!jSONListOfUnits[i].asString().empty()){
+      name += jSONListOfUnits[i].asString();
+    } else {
+      name += NA;
+    }
+    name += "]";
+    newCol->SetName(name.c_str());
+    for(int j = 0; j < data[i].second.size(); j++) {
+      newCol->SetValue(j, data[i].second[j]);
+    }
+    table->AddColumn(newCol);
+  }
 }
index 474b7f919bd9183929c6066a76f3d072002b5312..66badcfdaaa7b4b8fa755d42e27eaf7d12bd5af0 100644 (file)
 #ifndef __vtkJSONReader_h_
 #define __vtkJSONReader_h_
 
+#include "vtk_jsoncpp.h" // For json parser
 #include "vtkTableAlgorithm.h"
 
+
+//---------------------------------------------------
+class VTK_EXPORT vtkJSONException : public std::exception {
+ public:
+    vtkJSONException(const char *reason);
+    ~vtkJSONException() throw ();
+    const char* what() const throw();
+ protected:
+  std::string Reason;
+};
+
 class vtkStringArray;
-class vtkJSONParser;
 
 class VTK_EXPORT vtkJSONReader: public vtkTableAlgorithm
 {
@@ -38,16 +49,20 @@ public:
   vtkGetStringMacro(FileName);
   vtkSetStringMacro(FileName);
 
-  // Description:
-  // Determine whether the given file can be read
-  virtual int CanReadFile(const char* fname);
 
   // Description:
   // Request Data
   virtual int RequestData(vtkInformation*, 
                          vtkInformationVector**,
                          vtkInformationVector*);
+  // Decription:
+  // Parse the Json Value corresponding to the root data from the file
+  virtual int Parse(Json::Value& root, vtkTable *theTable);
 
+  // Decription:
+  // Verify if file exists and can be read by the parser
+  // If exists, parse into Jsoncpp data structure
+  int CanParseFile(const char *fname, Json::Value &root);
 
 protected:
   vtkJSONReader();
@@ -55,8 +70,6 @@ protected:
   // name of the file to read from
   char*            FileName;
 
-  vtkJSONParser*   Parser;
-
 private:
   vtkJSONReader(const vtkJSONReader&); // Not implemented.
   void operator=(const vtkJSONReader&); // Not implemented.
index 2f89cb40cad1a01e6142ddfa1ad5f336e7ce5f94..40ff17adda006b3d57d311d37d8119f663256139 100644 (file)
@@ -20,7 +20,7 @@
 #define __VTKJSONPARSERTEST_HXX__
 
 #include <cppunit/extensions/HelperMacros.h>
-#include <string.h>
+#include <string>
 
 class vtkJSONParserTest : public CppUnit::TestFixture
 {
index 7367368faba520ac21bf3e3678ccfb36c69e4c34..4d3c82bd8bda011c0b10b231bcb95ad84ddf78f7 100644 (file)
@@ -1147,6 +1147,7 @@ void MEDFileFieldRepresentationTree::loadMainStructureOfFile(const char *fileNam
     {
       AppendFieldFromMeshes(_ms,_fields);
     }
+  _ms->cartesianizeMe();
   _fields->removeFieldsWithoutAnyTimeStep();
   std::vector<std::string> meshNames(_ms->getMeshesNames());
   std::vector< MEDCouplingAutoRefCountObjectPtr<MEDFileFields> > fields_per_mesh(meshNames.size());
@@ -1439,7 +1440,7 @@ void MEDFileFieldRepresentationTree::AppendFieldFromMeshes(const ParaMEDMEM::MED
               std::vector<int> levsExt(mm->getNonEmptyLevelsExt());
               if(levsExt.size()==levs.size()+1)
                 {
-                  ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingMesh> m(mm->getGenMeshAtLevel(1));
+                  ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingMesh> m(mm->getMeshAtLevel(1));
                   ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f(ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES));
                   f->setMesh(m);
                   ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> arr(ParaMEDMEM::DataArrayDouble::New()); arr->alloc(m->getNumberOfNodes());
@@ -1454,7 +1455,7 @@ void MEDFileFieldRepresentationTree::AppendFieldFromMeshes(const ParaMEDMEM::MED
         }
       else
         {
-          ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingMesh> m(mm->getGenMeshAtLevel(0));
+          ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingMesh> m(mm->getMeshAtLevel(0));
           ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::MEDCouplingFieldDouble> f(ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS));
           f->setMesh(m);
           ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr<ParaMEDMEM::DataArrayDouble> arr(ParaMEDMEM::DataArrayDouble::New()); arr->alloc(f->getNumberOfTuplesExpected());
index 06ceb7a911cea4e01abf2b9b5c6d3ff4f1596a79..47c5e1ce766609956e18a74e279ec10413a6dac1 100644 (file)
@@ -452,7 +452,7 @@ int vtkExtractGroup::RequestInformation(vtkInformation *request, vtkInformationV
       if(!vtkExtractGroup::vtkExtractGroupInternal::IsInformationOK(inputInfo))
         {
         vtkErrorMacro("No SIL Data available ! The source of this filter must be MEDReader !");
-             return 0;
+        return 0;
         }
 
       this->SetSIL(vtkMutableDirectedGraph::SafeDownCast(inputInfo->Get(vtkMEDReader::META_DATA())));
@@ -568,95 +568,100 @@ int vtkExtractGroup::RequestData(vtkInformation *request, vtkInformationVector *
 //      std::cerr << "########################################## vtkExtractGroup::RequestData        ##########################################" << std::endl;
 //      request->Print(cout);
       vtkInformation* inputInfo=inputVector[0]->GetInformationObject(0);
-      vtkDataSet *input(vtkDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+      vtkMultiBlockDataSet *inputMB(vtkMultiBlockDataSet::SafeDownCast(inputInfo->Get(vtkDataObject::DATA_OBJECT())));
+      if(inputMB->GetNumberOfBlocks()!=1)
+        {
+          std::ostringstream oss; oss << "vtkExtractGroup::RequestData : input has not the right number of parts ! Expected 1 !";
+          if(this->HasObserver("ErrorEvent") )
+            this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+          else
+            vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+          vtkObject::BreakOnError();
+          return 0;
+        }
+      vtkDataSet *input(vtkDataSet::SafeDownCast(inputMB->GetBlock(0)));
       vtkInformation *info(input->GetInformation());
       vtkInformation *outInfo(outputVector->GetInformationObject(0));
-      vtkDataSet *output(vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
+      vtkMultiBlockDataSet *output(vtkMultiBlockDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT())));
       std::set<int> idsToKeep(this->Internal->getIdsToKeep());
       // first shrink the input
       bool catchAll,catchSmth;
       vtkSmartPointer<vtkThreshold> thres1(vtkSmartPointer<vtkThreshold>::New()),thres2(vtkSmartPointer<vtkThreshold>::New());
       vtkDataSet *tryOnCell(FilterFamilies<CellExtractor>(thres1,input,idsToKeep,this->InsideOut,
-                                                         MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
+                                                          MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME,"vtkDataObject::FIELD_ASSOCIATION_CELLS",catchAll,catchSmth));
       if(tryOnCell)
-       {
-         if(catchAll)
-           {
-             output->ShallowCopy(tryOnCell);
-             tryOnCell->Delete();//
-             return 1;
-           }
-         else
-           {
-             if(catchSmth)
-               {
-                 vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres2,input,idsToKeep,this->InsideOut,
-                                                                      MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
-                 if(tryOnNode && catchSmth)
-                   {
-                      vtkSmartPointer<vtkMultiBlockDataGroupFilter> mb(vtkSmartPointer<vtkMultiBlockDataGroupFilter>::New());
-                      vtkSmartPointer<vtkCompositeDataToUnstructuredGridFilter> cd(vtkSmartPointer<vtkCompositeDataToUnstructuredGridFilter>::New());
-                      mb->AddInputConnection(thres1->GetOutputPort());
-                      mb->AddInputConnection(thres2->GetOutputPort());
-                      cd->SetInputConnection(mb->GetOutputPort());
-                      cd->SetMergePoints(0);
-                      cd->Update();
-                     output->ShallowCopy(cd->GetOutput());
-                     tryOnCell->Delete();
-                     tryOnNode->Delete();
-                     return 1;
-                   }
-                 else
-                   {
-                     if(tryOnNode)
-                       tryOnNode->Delete();
-                     output->ShallowCopy(tryOnCell);
-                     tryOnCell->Delete();
-                     return 1;
-                   }
-               }
-             else
-               {
-                 vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
-                                                                      MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
-                 if(tryOnNode)
-                   {
-                     tryOnCell->Delete();
-                     output->ShallowCopy(tryOnNode);
-                     tryOnNode->Delete();
-                     return 1;
-                   }
-                 else
-                   {
-                     output->ShallowCopy(tryOnCell);
-                     tryOnCell->Delete();
-                     return 0;
-                   }
-               }
-           }
-       }
+        {
+          if(catchAll)
+            {
+              output->SetBlock(0,tryOnCell);
+              tryOnCell->Delete();//
+              return 1;
+            }
+          else
+            {
+              if(catchSmth)
+                {
+                  vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres2,input,idsToKeep,this->InsideOut,
+                                                                       MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
+                  if(tryOnNode && catchSmth)
+                    {
+                      output->SetBlock(0,tryOnCell);
+                      output->SetBlock(1,tryOnNode);
+                      tryOnCell->Delete();
+                      tryOnNode->Delete();
+                      return 1;
+                    }
+                  else
+                    {
+                      if(tryOnNode)
+                        tryOnNode->Delete();
+                      output->SetBlock(0,tryOnCell);
+                      tryOnCell->Delete();
+                      return 1;
+                    }
+                }
+              else
+                {
+                  vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
+                                                                       MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
+                  if(tryOnNode)
+                    {
+                      tryOnCell->Delete();
+                      output->SetBlock(0,tryOnNode);
+                      tryOnNode->Delete();
+                      return 1;
+                    }
+                  else
+                    {
+                      output->SetBlock(0,tryOnNode);
+                      tryOnCell->Delete();
+                      return 0;
+                    }
+                }
+            }
+        }
       else
-       {
-         vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
-                                                              MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
-         if(tryOnNode)
-           {
-             output->ShallowCopy(tryOnNode);
-             tryOnNode->Delete();//
-             return 1;
-           }
-         else
-           {
-             std::ostringstream oss; oss << "vtkExtractGroup::RequestData : The integer array with name \""<< MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME;
-             oss << "\" or \"" << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME << "\" does not exist ! The extraction of group and/or family is not possible !";
-             if(this->HasObserver("ErrorEvent") )
-               this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
-             else
-               vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
-             vtkObject::BreakOnError();
-             return 0;
-           }
-       }
+        {
+          vtkDataSet *tryOnNode(FilterFamilies<PointExtractor>(thres1,input,idsToKeep,this->InsideOut,
+                                                               MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth));
+          if(tryOnNode)
+            {
+              output->ShallowCopy(tryOnNode);
+              tryOnNode->Delete();//
+              return 1;
+            }
+          else
+            {
+              std::ostringstream oss; oss << "vtkExtractGroup::RequestData : The integer array with name \""<< MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_CELL_NAME;
+              oss << "\" or \"" << MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME << "\" does not exist ! The extraction of group and/or family is not possible !";
+              if(this->HasObserver("ErrorEvent") )
+                this->InvokeEvent("ErrorEvent",const_cast<char *>(oss.str().c_str()));
+              else
+                vtkOutputWindowDisplayErrorText(const_cast<char *>(oss.str().c_str()));
+              vtkObject::BreakOnError();
+              return 0;
+            }
+        }
     }
   catch(INTERP_KERNEL::Exception& e)
     {
index d3cca44b904e519b302d3ab6b01a28bf3efdfc9d..b7b06938b285d6e947848f00e24a220f4118ad7b 100644 (file)
 #ifndef vtkExtractGroup_h__
 #define vtkExtractGroup_h__
 
-#include "vtkUnstructuredGridAlgorithm.h"
+#include "vtkMultiBlockDataSetAlgorithm.h"
 
 class vtkMutableDirectedGraph;
 
-class VTK_EXPORT vtkExtractGroup: public vtkUnstructuredGridAlgorithm
+class VTK_EXPORT vtkExtractGroup: public vtkMultiBlockDataSetAlgorithm
 {
 public:
   static vtkExtractGroup* New();
-  vtkTypeMacro(vtkExtractGroup, vtkUnstructuredGridAlgorithm)
+  vtkTypeMacro(vtkExtractGroup, vtkMultiBlockDataSetAlgorithm)
   void PrintSelf(ostream& os, vtkIndent indent);
   virtual int GetNumberOfGroupsFlagsArrays();
   const char *GetGroupsFlagsArrayName(int index);
index a498d68556fb1f173c12400b85ae066a7b376a8a..46680b5de9d04f2fb03c2aa1fdb15d414045be25 100644 (file)
@@ -130,6 +130,10 @@ void vtkPVMetaDataInformation::CopyFromStream(const vtkClientServerStream* css)
     }
 }
 
+void vtkPVMetaDataInformation::AddInformation(vtkPVInformation*)
+{
+}
+
 //----------------------------------------------------------------------------
 void vtkPVMetaDataInformation::PrintSelf(ostream& os, vtkIndent indent)
 {
index 879d11ebff68c929b058494db80dfa8fb103c82e..106f671d3e0cee9b9659ff72e9c8748adc6180f1 100644 (file)
@@ -42,6 +42,7 @@ public:
   // Manage a serialized version of the information.
   virtual void CopyToStream(vtkClientServerStream*);
   virtual void CopyFromStream(const vtkClientServerStream*);
+  virtual void AddInformation(vtkPVInformation*);
   //ETX
 
   // Description:
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader0.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader0.png
new file mode 100644 (file)
index 0000000..d4967f9
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader0.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader10.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader10.png
new file mode 100644 (file)
index 0000000..4bab2af
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader10.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader11.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader11.png
new file mode 100644 (file)
index 0000000..fdc1ac7
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader11.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader12.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader12.png
new file mode 100644 (file)
index 0000000..906acff
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader12.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader13.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader13.png
new file mode 100644 (file)
index 0000000..ea4ebe9
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader13.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader14.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader14.png
new file mode 100644 (file)
index 0000000..ffc5019
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader14.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader15.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader15.png
new file mode 100644 (file)
index 0000000..7e78fd1
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader15.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader19.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader19.png
new file mode 100644 (file)
index 0000000..f05519f
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader19.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader2.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader2.png
new file mode 100644 (file)
index 0000000..d4b019a
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader2.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader3.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader3.png
new file mode 100644 (file)
index 0000000..654ac20
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader3.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader4.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader4.png
new file mode 100644 (file)
index 0000000..17c6a9b
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader4.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader5.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader5.png
new file mode 100644 (file)
index 0000000..5b3d99b
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader5.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader6.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader6.png
new file mode 100644 (file)
index 0000000..64b8247
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader6.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader7.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader7.png
new file mode 100644 (file)
index 0000000..c4de85a
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader7.png differ
diff --git a/src/Plugins/MEDReader/Test/Baselines/testMEDReader8.png b/src/Plugins/MEDReader/Test/Baselines/testMEDReader8.png
new file mode 100644 (file)
index 0000000..ebbd4f7
Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader8.png differ
index 77e434f5581089423c9c0c02fda9862b8b453a92..5f9c1c69f1f53c970e4e725cbf2356c973b7db3e 100644 (file)
@@ -17,7 +17,7 @@
 # See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 #
 
-SET(TEST_NUMBERS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18)
+SET(TEST_NUMBERS 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19)
 
 SET(TEST_INSTALL_DIRECTORY ${SALOME_INSTALL_SCRIPT_SCRIPTS}/test/MEDReader)
 
index 235a4042088743d66ffa659e9e6e08517332b6ae..f4f48a5dcca048d96e386df1cdcdea56aff1c1bd 100644 (file)
@@ -49,4 +49,6 @@ ExtractGroup1 = ExtractGroup(Input=reader)
 ExtractGroup1.AllGroups=["GRP_grp0","GRP_grp1"]
 ExtractGroup1.UpdatePipelineInformation()
 res=servermanager.Fetch(ExtractGroup1,0)
-assert(res.GetBlock(0).GetNumberOfCells()==3)
+assert(res.GetNumberOfBlocks()==2)
+assert(res.GetBlock(1).GetNumberOfCells()==1)
+assert(res.GetBlock(0).GetNumberOfCells()==2)
diff --git a/src/Plugins/MEDReader/Test/testMEDReader19.py b/src/Plugins/MEDReader/Test/testMEDReader19.py
new file mode 100644 (file)
index 0000000..ea2fcde
--- /dev/null
@@ -0,0 +1,90 @@
+from MEDLoader import *
+
+""" This is a non regression bug revealed during training session. The bug is linked to the native Threshold VTK filter. Corrected with PV version >= 4.4. (KW10658)
+There is still a problem when both image comparison and Fetch are enable together."""
+
+fname="testMEDReader19.med"
+imgName="testMEDReader19.png"
+meshName="mesh"
+mm=MEDFileUMesh()
+coo=DataArrayDouble([(-0.3,-0.3),(0.2,-0.3),(0.7,-0.3),(-0.3,0.2),(0.2,0.2),(0.7,0.2),(-0.3,0.7),(0.2,0.7),(0.7,0.7)])
+conn0=[[NORM_TRI3,1,4,2],[NORM_TRI3,4,5,2],[NORM_QUAD4,0,3,4,1],[NORM_QUAD4,6,7,4,3],[NORM_QUAD4,7,8,5,4]]
+conn1=[[NORM_SEG2,4,5],[NORM_SEG2,5,2],[NORM_SEG2,1,0],[NORM_SEG2,6,7]]
+m0=MEDCouplingUMesh() ; m0.setCoords(coo) ; m0.setMeshDimension(2) ; m0.allocateCells(0)
+for c in conn0:
+    m0.insertNextCell(c[0],c[1:])
+mm[0]=m0
+m1=MEDCouplingUMesh() ; m1.setCoords(coo) ; m1.setMeshDimension(1) ; m1.allocateCells(0)
+for c in conn1:
+    m1.insertNextCell(c[0],c[1:])
+mm[-1]=m1
+mm.setName(meshName)
+mm.write(fname,2)
+#
+#### import the simple module from the paraview
+from paraview.simple import *
+import vtk.test.Testing # this line must be here. If not SIGSEGV ! KW10658
+#### disable automatic camera reset on 'Show'
+paraview.simple._DisableFirstRenderCameraReset()
+# create a new 'MED Reader'
+testMEDReader19med = MEDReader(FileName=fname)
+testMEDReader19med.AllArrays = ['TS0/mesh/ComSup0/mesh@@][@@P0']
+testMEDReader19med.AllTimeSteps = ['0000']
+# Properties modified on testMEDReader19med
+testMEDReader19med.AllArrays = ['TS0/mesh/ComSup0/mesh@@][@@P0']
+
+# get active view
+renderView1 = GetActiveViewOrCreate('RenderView')
+
+# reset view to fit data
+renderView1.ResetCamera()
+
+#changing interaction mode based on data extents
+renderView1.InteractionMode = '2D'
+renderView1.CameraPosition = [0.2, 0.2, 10000.0]
+renderView1.CameraFocalPoint = [0.2, 0.2, 0.0]
+testMEDReader19med.UpdatePipeline()
+# create a new 'Extract Cell Type'
+extractCellType1 = ExtractCellType(Input=testMEDReader19med)
+extractCellType1.AllGeoTypes = []
+
+# Properties modified on extractCellType1
+extractCellType1.AllGeoTypes = ['TRI3']
+
+# show data in view
+extractCellType1Display = Show(extractCellType1, renderView1)
+# trace defaults for the display properties.
+extractCellType1Display.ColorArrayName = [None, '']
+extractCellType1Display.ScalarOpacityUnitDistance = 0.5
+extractCellType1Display.OpacityArray = [None, '']
+extractCellType1Display.RadiusArray = [None, '']
+extractCellType1Display.RadiusRange = [0.2, 0.7]
+extractCellType1Display.ConstantRadius = 0.7
+extractCellType1Display.PointSpriteDefaultsInitialized = 1
+extractCellType1Display.SelectInputVectors = [None, '']
+extractCellType1Display.WriteLog = ''
+
+
+renderView1.InteractionMode = '2D'
+renderView1.CameraPosition = [0.2, 0.2, 10000.0]
+renderView1.CameraFocalPoint = [0.2, 0.2, 0.0]
+renderView1.CameraParallelScale = 0.7071067811865476
+
+res=servermanager.Fetch(extractCellType1,0)
+assert(res.GetBlock(0).GetNumberOfCells()==2) # problem was here in PV4.3.1
+
+# compare with baseline image # Waiting KW return to uncomment this part because SIGSEGV in PV5.
+import os
+import sys
+try:
+  baselineIndex = sys.argv.index('-B')+1
+  baselinePath = sys.argv[baselineIndex]
+except:
+  print "Could not get baseline directory. Test failed."
+  exit(1)
+baseline_file = os.path.join(baselinePath, imgName)
+import vtk.test.Testing
+vtk.test.Testing.VTK_TEMP_DIR = vtk.util.misc.vtkGetTempDir()
+vtk.test.Testing.compareImage(GetActiveView().GetRenderWindow(), baseline_file, threshold=25)
+vtk.test.Testing.interact()
+
index 62906d3100796d4e1c25df45db452972ee6e2125..da9325f82f030589acd38f69546dd6462387f352 100644 (file)
@@ -151,34 +151,39 @@ int vtkParaMEDCorbaSource::RequestInformation(vtkInformation* request, vtkInform
     //tony->SetInformation(myInfo);
     //myInfo->Set(vtkDataObject::DATA_OBJECT(),tony);
     //
-    CORBA::ORB_var *OrbC=(CORBA::ORB_var *)this->Orb;
-    CORBA::Object_var obj=(*OrbC)->string_to_object(&IOR[0]);
-    //
-    Engines::MPIObject_ptr objPara=Engines::MPIObject::_narrow(obj);
-    if(CORBA::is_nil(objPara))
-    {//sequential
-      this->TotalNumberOfPieces=1;
-      SALOME_MED::MEDCouplingMultiFieldsCorbaInterface_var multiPtr=SALOME_MED::MEDCouplingMultiFieldsCorbaInterface::_narrow(obj);
-      if(!CORBA::is_nil(multiPtr))
-      {//Request for multiFields
-        delete mfieldsFetcher;
-        mfieldsFetcher=new ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher(BufferingPolicy,multiPtr);
-        std::vector<double> tsteps=mfieldsFetcher->getTimeStepsForPV();
-        double timeRange[2];
-        timeRange[0]=tsteps.front();
-        timeRange[1]=tsteps.back();
-        myInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&tsteps[0],tsteps.size());
-        myInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),timeRange,2);
+    try {
+      CORBA::ORB_var *OrbC=(CORBA::ORB_var *)this->Orb;
+      CORBA::Object_var obj=(*OrbC)->string_to_object(&IOR[0]);
+      //
+      Engines::MPIObject_ptr objPara=Engines::MPIObject::_narrow(obj);
+      if(CORBA::is_nil(objPara))
+      {//sequential
+        this->TotalNumberOfPieces=1;
+        SALOME_MED::MEDCouplingMultiFieldsCorbaInterface_var multiPtr=SALOME_MED::MEDCouplingMultiFieldsCorbaInterface::_narrow(obj);
+        if(!CORBA::is_nil(multiPtr))
+        {//Request for multiFields
+          delete mfieldsFetcher;
+          mfieldsFetcher=new ParaMEDMEM2VTK::MEDCouplingMultiFieldsFetcher(BufferingPolicy,multiPtr);
+          std::vector<double> tsteps=mfieldsFetcher->getTimeStepsForPV();
+          double timeRange[2];
+          timeRange[0]=tsteps.front();
+          timeRange[1]=tsteps.back();
+          myInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&tsteps[0],tsteps.size());
+          myInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),timeRange,2);
+        }
       }
+      else
+      {
+        Engines::IORTab *iorTab=objPara->tior();
+        this->TotalNumberOfPieces=iorTab->length();
+        delete iorTab;
+        CORBA::release(objPara);
+      }
+      myInfo->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
     }
-    else
-    {
-      Engines::IORTab *iorTab=objPara->tior();
-      this->TotalNumberOfPieces=iorTab->length();
-      delete iorTab;
-      CORBA::release(objPara);
+    catch(CORBA::Exception&) {
+      vtkErrorMacro("On fetching object error occurs");
     }
-    myInfo->Set(CAN_HANDLE_PIECE_REQUEST(), 1);
   }
   return 1;
 }
@@ -196,72 +201,77 @@ int vtkParaMEDCorbaSource::RequestData(vtkInformation* request, vtkInformationVe
   double reqTS = 0;
   if(outInfo->Has(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP()))
     reqTS = outInfo->Get(vtkStreamingDemandDrivenPipeline::UPDATE_TIME_STEP());
-  //Client request on ORB.
-  CORBA::ORB_var *OrbC=(CORBA::ORB_var *)this->Orb;
-  CORBA::Object_var obj=(*OrbC)->string_to_object(&IOR[0]);
-  //
-  Engines::MPIObject_var objPara=Engines::MPIObject::_narrow(obj);
-  if(CORBA::is_nil(objPara))
-  {//sequential
-    SALOME_MED::MEDCouplingMeshCorbaInterface_var meshPtr=SALOME_MED::MEDCouplingMeshCorbaInterface::_narrow(obj);
-    if(!CORBA::is_nil(meshPtr))
-    {
-      bool dummy;//bug VTK
-      vtkDataSet *ret=ParaMEDMEM2VTK::BuildFromMEDCouplingMeshInstance(meshPtr,dummy);//bug VTK
-      if(!ret)
-        return 0;
-      ret0->SetBlock(0,ret);
-      ret->Delete();
-      return 1;
-    }
-    SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_var fieldPtr=SALOME_MED::MEDCouplingFieldDoubleCorbaInterface::_narrow(obj);
-    if(!CORBA::is_nil(fieldPtr))
-    {
-      std::vector<double> ret2;
-      vtkDataSet *ret=ParaMEDMEM2VTK::BuildFullyFilledFromMEDCouplingFieldDoubleInstance(fieldPtr,ret2);
-      if(!ret)
+  try {
+    //Client request on ORB.
+    CORBA::ORB_var *OrbC=(CORBA::ORB_var *)this->Orb;
+    CORBA::Object_var obj=(*OrbC)->string_to_object(&IOR[0]);
+    //
+    Engines::MPIObject_var objPara=Engines::MPIObject::_narrow(obj);
+    if(CORBA::is_nil(objPara))
+    {//sequential
+      SALOME_MED::MEDCouplingMeshCorbaInterface_var meshPtr=SALOME_MED::MEDCouplingMeshCorbaInterface::_narrow(obj);
+      if(!CORBA::is_nil(meshPtr))
       {
-        vtkErrorMacro("On single field CORBA fetching an error occurs !");
-        return 0;
+        bool dummy;//bug VTK
+        vtkDataSet *ret=ParaMEDMEM2VTK::BuildFromMEDCouplingMeshInstance(meshPtr,dummy);//bug VTK
+        if(!ret)
+          return 0;
+        ret0->SetBlock(0,ret);
+        ret->Delete();
+        return 1;
       }
-      ret0->SetBlock(0,ret);
-      ret->Delete();
-      //
-      double timeRange[2];
-      timeRange[0]=ret2[0];
-      timeRange[1]=ret2[0];
-      outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&ret2[0],1);
-      outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),timeRange,2);
-      ret0->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(),ret2[0]);
-      return 1;
+      SALOME_MED::MEDCouplingFieldDoubleCorbaInterface_var fieldPtr=SALOME_MED::MEDCouplingFieldDoubleCorbaInterface::_narrow(obj);
+      if(!CORBA::is_nil(fieldPtr))
+      {
+        std::vector<double> ret2;
+        vtkDataSet *ret=ParaMEDMEM2VTK::BuildFullyFilledFromMEDCouplingFieldDoubleInstance(fieldPtr,ret2);
+        if(!ret)
+        {
+          vtkErrorMacro("On single field CORBA fetching an error occurs !");
+          return 0;
+        }
+        ret0->SetBlock(0,ret);
+        ret->Delete();
+        //
+        double timeRange[2];
+        timeRange[0]=ret2[0];
+        timeRange[1]=ret2[0];
+        outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_STEPS(),&ret2[0],1);
+        outInfo->Set(vtkStreamingDemandDrivenPipeline::TIME_RANGE(),timeRange,2);
+        ret0->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(),ret2[0]);
+        return 1;
+      }
+      SALOME_MED::MEDCouplingMultiFieldsCorbaInterface_var multiPtr=SALOME_MED::MEDCouplingMultiFieldsCorbaInterface::_narrow(obj);
+      if(!CORBA::is_nil(multiPtr))
+      {
+        vtkDataSet *ret=mfieldsFetcher->buildDataSetOnTime(reqTS);
+        if(!ret)
+        {
+          vtkErrorMacro("On multi fields CORBA fetching an error occurs !");
+          return 0;
+        }
+        ret0->SetBlock(0,ret);
+        ret->Delete();
+        ret0->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(),reqTS);
+        return 1;
+      }
+      vtkErrorMacro("Unrecognized sequential CORBA reference !");
+      return 0;
     }
-    SALOME_MED::MEDCouplingMultiFieldsCorbaInterface_var multiPtr=SALOME_MED::MEDCouplingMultiFieldsCorbaInterface::_narrow(obj);
-    if(!CORBA::is_nil(multiPtr))
+    else
     {
-      vtkDataSet *ret=mfieldsFetcher->buildDataSetOnTime(reqTS);
-      if(!ret)
+      SALOME_MED::ParaMEDCouplingFieldDoubleCorbaInterface_var paraFieldCorba=SALOME_MED::ParaMEDCouplingFieldDoubleCorbaInterface::_narrow(obj);
+      if(!CORBA::is_nil(paraFieldCorba))
       {
-        vtkErrorMacro("On multi fields CORBA fetching an error occurs !");
-        return 0;
+        ParaMEDMEM2VTK::FillMEDCouplingParaFieldDoubleInstanceFrom(paraFieldCorba,this->StartPiece,this->EndPiece,ret0);
+        return 1;
       }
-      ret0->SetBlock(0,ret);
-      ret->Delete();
-      ret0->GetInformation()->Set(vtkDataObject::DATA_TIME_STEP(),reqTS);
-      return 1;
+      vtkErrorMacro("Unrecognized parallel CORBA reference !");
+      return 0;
     }
-    vtkErrorMacro("Unrecognized sequential CORBA reference !");
-    return 0;
   }
-  else
-  {
-    SALOME_MED::ParaMEDCouplingFieldDoubleCorbaInterface_var paraFieldCorba=SALOME_MED::ParaMEDCouplingFieldDoubleCorbaInterface::_narrow(obj);
-    if(!CORBA::is_nil(paraFieldCorba))
-    {
-      ParaMEDMEM2VTK::FillMEDCouplingParaFieldDoubleInstanceFrom(paraFieldCorba,this->StartPiece,this->EndPiece,ret0);
-      return 1;
-    }
-    vtkErrorMacro("Unrecognized parallel CORBA reference !");
-    return 0;
+  catch(CORBA::Exception&) {
+    vtkErrorMacro("On fetching object error occurs");
   }
 }