From: vsr Date: Fri, 15 Jan 2016 06:27:26 +0000 (+0300) Subject: Merge branch 'V8_0_BR' X-Git-Tag: V8_0_0a2^0 X-Git-Url: http://git.salome-platform.org/gitweb/?a=commitdiff_plain;h=c2fb6da45f443de1cacaebb2873904debc00bfc3;hp=322d31842848e442a887fa4fa3c46a899c200f38;p=modules%2Fparavis.git Merge branch 'V8_0_BR' --- diff --git a/src/Plugins/CMakeLists.txt b/src/Plugins/CMakeLists.txt index ff1b52b3..8fca10f7 100755 --- a/src/Plugins/CMakeLists.txt +++ b/src/Plugins/CMakeLists.txt @@ -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 index 00000000..d66a9453 --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/CMakeLists.txt @@ -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 index 00000000..f6990b55 --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/GhostCellsGenerator.xml @@ -0,0 +1,44 @@ + + + + + + + + + + + + + + + This property specifies the input to the ghost cells generator. + + + Specify if the filter must take benefit of global point ids if they exist or if + point coordinates should be used instead. + + + + 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. + + + + + + + + + diff --git a/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx b/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx new file mode 100644 index 00000000..7cfcf9e2 --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.cxx @@ -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 +#include +#include + +//---------------------------------------------------------------------------- +// Helpers +namespace +{ +template +bool AllGatherV(vtkMultiProcessController* controller, + const T* localV, + vtkIdType localSize, + std::vector& globalV, + std::vector& sizes, + std::vector& 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 GlobalToLocalPointIdMap; + std::vector AllGlobalIdsOfSurfacePoints; + + // For point coordinates + vtkNew LocalPoints; + std::vector LocalPointsMap; + std::vector AllPointsOfSurfacePoints; + + std::vector AllSizes; + std::vector AllOffsets; + std::map > NeighborRanksCells; + std::map 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 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 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( + 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 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(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 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::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 cellIdsList; + vtkNew extractCells; + extractCells->SetInputData(this->Internals->Input); + std::map >::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& cellsToShare = iter->second; + cellIdsList->SetNumberOfIds(cellsToShare.size()); + std::set::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(this->Internals->NeighborRanksCells.size()); + std::vector neighborGrids; + neighborGrids.reserve(nbNeighbors); + + // First create requests to receive the size of the mesh to receive + std::map >::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 inputCopy; + inputCopy->ShallowCopy(this->Internals->Input); + inputCopy->AllocatePointGhostArray(); + inputCopy->AllocateCellGhostArray(); + + // MergeCells merge input + grids that contains ghost cells to the output grid + vtkNew mergeCells; + mergeCells->SetUnstructuredGrid(output); + mergeCells->SetTotalNumberOfCells(totalNbCells); + mergeCells->SetTotalNumberOfPoints(totalNbPoints); + mergeCells->SetTotalNumberOfDataSets( + 1 + static_cast(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 index 00000000..8102d82e --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/vtkPUnstructuredGridGhostCellsGenerator.h @@ -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 +//
    +//
  • A step of 'all reduce' (each processor send/receive data to/from +// all other processors. +//
  • The code currently assumes one grid per rank.
  • +//
  • PointData and CellData must match across partitions/processes.
  • +//
+// +// .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 index 00000000..b47aad61 --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.cxx @@ -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 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 index 00000000..9ad1b20c --- /dev/null +++ b/src/Plugins/GhostCellsGenerator/vtkPVUnstructuredGridGhostCellsGenerator.h @@ -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 +//
    +//
  • A step of 'all reduce' (each processor send/receive data to/from +// all other processors. +//
  • The code currently assumes one grid per rank.
  • +//
  • PointData and CellData must match across partitions/processes.
  • +//
+// +// .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 diff --git a/src/Plugins/JSONReader/CMakeLists.txt b/src/Plugins/JSONReader/CMakeLists.txt index 163fef31..1f5aeb09 100644 --- a/src/Plugins/JSONReader/CMakeLists.txt +++ b/src/Plugins/JSONReader/CMakeLists.txt @@ -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 diff --git a/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt b/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt index 6fd4e2c4..eac829fa 100644 --- a/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt +++ b/src/Plugins/JSONReader/ParaViewPlugin/CMakeLists.txt @@ -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 ) diff --git a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx index adec0627..cc1f6703 100644 --- a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx +++ b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.cxx @@ -19,42 +19,114 @@ // Author: Roman NIKOLAEV #include "vtkJSONReader.h" -#include "vtkJSONParser.h" #include #include #include #include #include +#include #include #include #include +#include +#include #include #include +// 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>> DataType; + Container(){} + void initKeys(std::vector &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 '"<())); + } + } + + void addValue(std::string key, double value, std::string& err) { + if( !checkVar(key.c_str()) ) { + std::ostringstream oss; + oss<<"Bad key value '"<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: "<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<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<HasObserver("ErrorEvent") ) + { + this->InvokeEvent("ErrorEvent",const_cast(oss.str().c_str())); + } + else + { + vtkOutputWindowDisplayErrorText(const_cast(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(oss.str().c_str())); + } + else { + vtkOutputWindowDisplayErrorText(const_cast(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 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(< 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(s.c_str())); + } + else { + vtkOutputWindowDisplayWarningText(const_cast(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); + } } diff --git a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h index 474b7f91..66badcfd 100644 --- a/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h +++ b/src/Plugins/JSONReader/ParaViewPlugin/vtkJSONReader.h @@ -21,10 +21,21 @@ #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. diff --git a/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx b/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx index 2f89cb40..40ff17ad 100644 --- a/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx +++ b/src/Plugins/JSONReader/Test/vtkJSONParserTest.hxx @@ -20,7 +20,7 @@ #define __VTKJSONPARSERTEST_HXX__ #include -#include +#include class vtkJSONParserTest : public CppUnit::TestFixture { diff --git a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx index 7367368f..4d3c82bd 100644 --- a/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx +++ b/src/Plugins/MEDReader/IO/MEDFileFieldRepresentationTree.cxx @@ -1147,6 +1147,7 @@ void MEDFileFieldRepresentationTree::loadMainStructureOfFile(const char *fileNam { AppendFieldFromMeshes(_ms,_fields); } + _ms->cartesianizeMe(); _fields->removeFieldsWithoutAnyTimeStep(); std::vector meshNames(_ms->getMeshesNames()); std::vector< MEDCouplingAutoRefCountObjectPtr > fields_per_mesh(meshNames.size()); @@ -1439,7 +1440,7 @@ void MEDFileFieldRepresentationTree::AppendFieldFromMeshes(const ParaMEDMEM::MED std::vector levsExt(mm->getNonEmptyLevelsExt()); if(levsExt.size()==levs.size()+1) { - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr m(mm->getGenMeshAtLevel(1)); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr m(mm->getMeshAtLevel(1)); ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr f(ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_NODES)); f->setMesh(m); ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr arr(ParaMEDMEM::DataArrayDouble::New()); arr->alloc(m->getNumberOfNodes()); @@ -1454,7 +1455,7 @@ void MEDFileFieldRepresentationTree::AppendFieldFromMeshes(const ParaMEDMEM::MED } else { - ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr m(mm->getGenMeshAtLevel(0)); + ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr m(mm->getMeshAtLevel(0)); ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr f(ParaMEDMEM::MEDCouplingFieldDouble::New(ParaMEDMEM::ON_CELLS)); f->setMesh(m); ParaMEDMEM::MEDCouplingAutoRefCountObjectPtr arr(ParaMEDMEM::DataArrayDouble::New()); arr->alloc(f->getNumberOfTuplesExpected()); diff --git a/src/Plugins/MEDReader/IO/vtkExtractGroup.cxx b/src/Plugins/MEDReader/IO/vtkExtractGroup.cxx index 06ceb7a9..47c5e1ce 100644 --- a/src/Plugins/MEDReader/IO/vtkExtractGroup.cxx +++ b/src/Plugins/MEDReader/IO/vtkExtractGroup.cxx @@ -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(oss.str().c_str())); + else + vtkOutputWindowDisplayErrorText(const_cast(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 idsToKeep(this->Internal->getIdsToKeep()); // first shrink the input bool catchAll,catchSmth; vtkSmartPointer thres1(vtkSmartPointer::New()),thres2(vtkSmartPointer::New()); vtkDataSet *tryOnCell(FilterFamilies(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(thres2,input,idsToKeep,this->InsideOut, - MEDFileFieldRepresentationLeavesArrays::FAMILY_ID_NODE_NAME,"vtkDataObject::FIELD_ASSOCIATION_POINTS",catchAll,catchSmth)); - if(tryOnNode && catchSmth) - { - vtkSmartPointer mb(vtkSmartPointer::New()); - vtkSmartPointer cd(vtkSmartPointer::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(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(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(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(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(oss.str().c_str())); - else - vtkOutputWindowDisplayErrorText(const_cast(oss.str().c_str())); - vtkObject::BreakOnError(); - return 0; - } - } + { + vtkDataSet *tryOnNode(FilterFamilies(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(oss.str().c_str())); + else + vtkOutputWindowDisplayErrorText(const_cast(oss.str().c_str())); + vtkObject::BreakOnError(); + return 0; + } + } } catch(INTERP_KERNEL::Exception& e) { diff --git a/src/Plugins/MEDReader/IO/vtkExtractGroup.h b/src/Plugins/MEDReader/IO/vtkExtractGroup.h index d3cca44b..b7b06938 100644 --- a/src/Plugins/MEDReader/IO/vtkExtractGroup.h +++ b/src/Plugins/MEDReader/IO/vtkExtractGroup.h @@ -21,15 +21,15 @@ #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); diff --git a/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.cxx b/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.cxx index a498d685..46680b5d 100644 --- a/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.cxx +++ b/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.cxx @@ -130,6 +130,10 @@ void vtkPVMetaDataInformation::CopyFromStream(const vtkClientServerStream* css) } } +void vtkPVMetaDataInformation::AddInformation(vtkPVInformation*) +{ +} + //---------------------------------------------------------------------------- void vtkPVMetaDataInformation::PrintSelf(ostream& os, vtkIndent indent) { diff --git a/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.h b/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.h index 879d11eb..106f671d 100644 --- a/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.h +++ b/src/Plugins/MEDReader/ParaViewPlugin/vtkPVMetaDataInformation.h @@ -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 index 00000000..d4967f92 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 index 00000000..4bab2af8 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 index 00000000..fdc1ac74 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 index 00000000..906acffb 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 index 00000000..ea4ebe98 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 index 00000000..ffc50195 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 index 00000000..7e78fd13 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 index 00000000..f05519f4 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 index 00000000..d4b019a5 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 index 00000000..654ac20e 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 index 00000000..17c6a9b6 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 index 00000000..5b3d99b6 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 index 00000000..64b8247f 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 index 00000000..c4de85aa 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 index 00000000..ebbd4f77 Binary files /dev/null and b/src/Plugins/MEDReader/Test/Baselines/testMEDReader8.png differ diff --git a/src/Plugins/MEDReader/Test/CMakeLists.txt b/src/Plugins/MEDReader/Test/CMakeLists.txt index 77e434f5..5f9c1c69 100644 --- a/src/Plugins/MEDReader/Test/CMakeLists.txt +++ b/src/Plugins/MEDReader/Test/CMakeLists.txt @@ -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) diff --git a/src/Plugins/MEDReader/Test/testMEDReader18.py b/src/Plugins/MEDReader/Test/testMEDReader18.py index 235a4042..f4f48a5d 100644 --- a/src/Plugins/MEDReader/Test/testMEDReader18.py +++ b/src/Plugins/MEDReader/Test/testMEDReader18.py @@ -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 index 00000000..ea2fcde8 --- /dev/null +++ b/src/Plugins/MEDReader/Test/testMEDReader19.py @@ -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() + diff --git a/src/Plugins/ParaMEDCorba/vtkParaMEDCorbaSource.cxx b/src/Plugins/ParaMEDCorba/vtkParaMEDCorbaSource.cxx index 62906d31..da9325f8 100644 --- a/src/Plugins/ParaMEDCorba/vtkParaMEDCorbaSource.cxx +++ b/src/Plugins/ParaMEDCorba/vtkParaMEDCorbaSource.cxx @@ -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 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 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 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 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"); } }