Commit 1a51d03f authored by Utkarsh Ayachit's avatar Utkarsh Ayachit

BUG #14794: Reenable parallel volume rendering for images.

During VTK refactoring of extents, parallel volume rendering was broken.
Fixing it by bringing back vtkPExtentTranslator (formerly called
vtkPVTrivialExtentTranslator) and making vtkImageVolumeRepresentation
use it to determine image extents across all ranks.

Also added a new test that tests volume rendering in parallel.

Change-Id: I72d06d0bebf14f71f7db6a2a345f668fa63ad16b
parent 54939844
......@@ -165,6 +165,7 @@ SET (TESTS_WITH_BASELINES
${CMAKE_CURRENT_SOURCE_DIR}/Flow2.xml
${CMAKE_CURRENT_SOURCE_DIR}/Fractal2D.xml
${CMAKE_CURRENT_SOURCE_DIR}/H5PartReaderPlugin.xml
${CMAKE_CURRENT_SOURCE_DIR}/ImageVolumeRendering.xml
${CMAKE_CURRENT_SOURCE_DIR}/LoadPlugins.xml
${CMAKE_CURRENT_SOURCE_DIR}/LoadSaveStateAnimation.xml
${CMAKE_CURRENT_SOURCE_DIR}/LoadState.xml
......@@ -412,6 +413,8 @@ SET (CompositeSurfaceSelection_DISABLE_CRS TRUE)
# mode.
SET (Clip_DISABLE_CRS TRUE)
# Image volume rendering not supported in CRS mode.
set (ImageVolumeRendering_DISABLE_CRS TRUE)
# These Xdmf tests have wireframes, hence the increased thresholds.
SET (XdmfReadImageData_THRESHOLD 20)
......
<?xml version="1.0" ?>
<pqevents>
<!-- This test image volume rendering (forcing remote rendering) -->
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuTools" />
<pqevent object="pqClientMainWindow/menubar/menuTools" command="activate" arguments="actionTesting_Window_Size" />
<pqevent object="pqClientMainWindow/menubar/menu_Edit" command="activate" arguments="actionEditSettings" />
<pqevent object="pqClientMainWindow/ApplicationSettings/tabBar" command="set_tab_with_text" arguments="Render View" />
<pqevent object="pqClientMainWindow/ApplicationSettings/stackedWidget/ScrollAreaRenderViewSettings/qt_scrollarea_viewport/Container/ProxyWidget/RemoteRenderThreshold/DoubleRangeWidget/LineEdit" command="set_string" arguments="2" />
<pqevent object="pqClientMainWindow/ApplicationSettings/buttonBox/1QPushButton2" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/ApplicationSettings/buttonBox/1QPushButton0" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuSources" />
<pqevent object="pqClientMainWindow/menubar/menuSources" command="activate" arguments="RTAnalyticSource" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit0" command="set_string" arguments="-50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit1" command="set_string" arguments="50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit2" command="set_string" arguments="-50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit3" command="set_string" arguments="50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit4" command="set_string" arguments="-50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/WholeExtent/LineEdit5" command="set_string" arguments="50" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/representationToolbar/displayRepresentation/comboBox" command="set_string" arguments="Volume" />
<pqevent object="pqClientMainWindow/menubar" command="activate" arguments="menuSources" />
<pqevent object="pqClientMainWindow/menubar/menuSources" command="activate" arguments="SphereSource" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/Radius/LineEdit0" command="set_string" arguments="60" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/ThetaResolution/LineEdit0" command="set_string" arguments="80" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/scrollArea/qt_scrollarea_viewport/scrollAreaWidgetContents/PropertiesFrame/ProxyPanel/PhiResolution/LineEdit0" command="set_string" arguments="80" />
<pqevent object="pqClientMainWindow/propertiesDock/propertiesPanel/Accept" command="activate" arguments="" />
<!-- set camera to look down side ways-->
<pqevent object="pqClientMainWindow/centralwidget/MultiViewWidget/CoreWidget/qt_tabwidget_stackedwidget/MultiViewWidget1/Frame.0/CameraButton" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqCameraDialog/orientationsGroup/rollAngle" command="set_double" arguments="45" />
<pqevent object="pqClientMainWindow/pqCameraDialog/orientationsGroup/rollButton" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqCameraDialog/orientationsGroup/elevationAngle" command="set_double" arguments="45" />
<pqevent object="pqClientMainWindow/pqCameraDialog/orientationsGroup/elevationButton" command="activate" arguments="" />
<pqevent object="pqClientMainWindow/pqCameraDialog/closeButton" command="activate" arguments="" />
<!-- make Wavelet source active in pipeline browser -->
<pqevent object="pqClientMainWindow/pipelineBrowserDock/pipelineBrowser" command="mousePress" arguments="1,1,0,61,10,/0:0/0:0" />
<pqevent object="pqClientMainWindow/pipelineBrowserDock/pipelineBrowser" command="mouseRelease" arguments="1,0,0,61,10,/0:0/0:0" />
<pqevent object="pqClientMainWindow/cameraToolbar/actionZoomToData" command="activate" arguments="" />
</pqevents>
......@@ -51,6 +51,7 @@ set (Module_SRCS
vtkMoleculeRepresentation.cxx
vtkMPIMoveData.cxx
vtkOutlineRepresentation.cxx
vtkPExtentTranslator.cxx
vtkPVBagChartRepresentation.cxx
vtkPVBoxChartRepresentation.cxx
vtkPVCacheKeeper.cxx
......@@ -111,6 +112,9 @@ endif()
set_source_files_properties(
vtkCacheSizeKeeper
# No need to wrap vtkPExtentTranslator, its an internal class.
vtkPExtentTranslator
WRAP_EXCLUDE
)
......
......@@ -21,8 +21,10 @@
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMath.h"
#include "vtkNew.h"
#include "vtkObjectFactory.h"
#include "vtkOutlineSource.h"
#include "vtkPExtentTranslator.h"
#include "vtkPolyDataMapper.h"
#include "vtkPVCacheKeeper.h"
#include "vtkPVLODVolume.h"
......@@ -135,20 +137,20 @@ void vtkImageVolumeRepresentation::PassOrderedCompositingInformation(
vtkAlgorithm* inputAlgo = connection->GetProducer();
vtkStreamingDemandDrivenPipeline* sddp =
vtkStreamingDemandDrivenPipeline::SafeDownCast(inputAlgo->GetExecutive());
// vtkExtentTranslator* translator =
// sddp->GetExtentTranslator(connection->GetIndex());
int extent[6] = {1, -1, 1, -1, 1, -1};
sddp->GetWholeExtent(sddp->GetOutputInformation(connection->GetIndex()),
extent);
double origin[3], spacing[3];
vtkImageData* image = vtkImageData::SafeDownCast(
inputAlgo->GetOutputDataObject(connection->GetIndex()));
image->GetOrigin(origin);
image->GetSpacing(spacing);
// vtkPVRenderView::SetOrderedCompositingInformation(
// inInfo, self, translator, extent, origin, spacing);
vtkNew<vtkPExtentTranslator> translator;
translator->GatherExtents(image);
vtkPVRenderView::SetOrderedCompositingInformation(
inInfo, self, translator.GetPointer(), extent, origin, spacing);
}
}
......
/*=========================================================================
Program: ParaView
Module: $RCSfile: vtkPExtentTranslator.cxx,v $
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkPExtentTranslator.h"
#include "vtkImageData.h"
#include "vtkMultiProcessController.h"
#include "vtkObjectFactory.h"
#include "vtkRectilinearGrid.h"
#include "vtkStructuredGrid.h"
#include <cassert>
#include <vector>
class vtkPExtentTranslatorInternals
{
public:
std::vector<int> AllProcessExtents;
};
vtkStandardNewMacro(vtkPExtentTranslator);
//----------------------------------------------------------------------------
vtkPExtentTranslator::vtkPExtentTranslator()
{
this->Internals = new vtkPExtentTranslatorInternals;
}
//----------------------------------------------------------------------------
vtkPExtentTranslator::~vtkPExtentTranslator()
{
delete this->Internals;
this->Internals = NULL;
}
//----------------------------------------------------------------------------
int vtkPExtentTranslatorPieceToExtentThreadSafe(
int *resultExtent, vtkDataSet* dataSet)
{
// this is really only meant for topologically structured grids
if (vtkImageData* id = vtkImageData::SafeDownCast(dataSet))
{
id->GetExtent(resultExtent);
}
else if (vtkStructuredGrid* sd = vtkStructuredGrid::SafeDownCast(dataSet))
{
sd->GetExtent(resultExtent);
}
else if (vtkRectilinearGrid* rd = vtkRectilinearGrid::SafeDownCast(dataSet))
{
rd->GetExtent(resultExtent);
}
else
{
return 0;
}
return 1;
}
//-----------------------------------------------------------------------------
int vtkPExtentTranslator::PieceToExtentThreadSafe(
int piece, int vtkNotUsed(numPieces), int vtkNotUsed(ghostLevel), int *wholeExtent,
int *resultExtent, int vtkNotUsed(splitMode), int vtkNotUsed(byPoints))
{
assert(piece >= 0);
assert(
static_cast<int>(this->Internals->AllProcessExtents.size()) % 6 == 0);
if (this->Internals->AllProcessExtents.size() >= 6)
{
if (static_cast<size_t>(piece*6) >= this->Internals->AllProcessExtents.size())
{
vtkErrorMacro("Invalid piece.");
return 0;
}
memcpy(resultExtent, &this->Internals->AllProcessExtents[piece*6], sizeof(int)*6);
return 1;
}
vtkErrorMacro("GatherExtents must be called before this method");
return 0;
}
//----------------------------------------------------------------------------
void vtkPExtentTranslator::GatherExtents(vtkDataSet* dataset)
{
if (dataset == NULL)
{
this->Internals->AllProcessExtents.clear();
return;
}
vtkMultiProcessController* controller = vtkMultiProcessController::GetGlobalController();
int myExtent[6];
vtkPExtentTranslatorPieceToExtentThreadSafe(myExtent, dataset);
int myId = controller? controller->GetLocalProcessId() : 0;
int numProcs = controller? controller->GetNumberOfProcesses() : 1;
assert(numProcs >= 1);
this->Internals->AllProcessExtents.resize(numProcs*6);
if (numProcs > 1)
{
controller->AllGather(
myExtent, &(this->Internals->AllProcessExtents[0]), 6);
}
else
{
assert(myId == 0);
memcpy(&this->Internals->AllProcessExtents[0], myExtent, sizeof(int)*6);
}
}
//----------------------------------------------------------------------------
void vtkPExtentTranslator::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os, indent);
}
/*=========================================================================
Program: ParaView
Module: $RCSfile: vtkPExtentTranslator.h,v $
Copyright (c) Kitware, Inc.
All rights reserved.
See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 vtkPExtentTranslator - extent translator that collects information
// about extents from multiple processes in parallel.
// .SECTION Description
// vtkPExtentTranslator is used by vtkImageVolumeRepresentation to collect
// information about image extents on all the ranks. This is resurrected version
// of vtkPVTrivialExtentTranslator.
#ifndef __vtkPExtentTranslator_h
#define __vtkPExtentTranslator_h
#include "vtkExtentTranslator.h"
#include "vtkPVClientServerCoreRenderingModule.h" // needed for export macro
class vtkDataSet;
class vtkPExtentTranslatorInternals;
class VTKPVCLIENTSERVERCORERENDERING_EXPORT vtkPExtentTranslator : public vtkExtentTranslator
{
public:
static vtkPExtentTranslator* New();
vtkTypeMacro(vtkPExtentTranslator, vtkExtentTranslator);
void PrintSelf(ostream& os, vtkIndent indent);
// Description:
// If DataSet is topologically regular, each process will only know
// about its own subextent. This function does an allreduce to make sure
// that each process knows the subextent of every process.
void GatherExtents(vtkDataSet* dataset);
//BTX
protected:
vtkPExtentTranslator();
~vtkPExtentTranslator();
virtual int PieceToExtentThreadSafe(int vtkNotUsed(piece),
int vtkNotUsed(numPieces),
int vtkNotUsed(ghostLevel),
int *wholeExtent, int *resultExtent,
int vtkNotUsed(splitMode),
int vtkNotUsed(byPoints));
private:
vtkPExtentTranslator(const vtkPExtentTranslator&); // Not implemented
void operator=(const vtkPExtentTranslator&); // Not implemented
vtkPExtentTranslatorInternals* Internals;
//ETX
};
#endif
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment