mirror of
https://github.com/OpenFOAM/ThirdParty-6.git
synced 2025-12-08 06:57:43 +00:00
387 lines
12 KiB
C++
387 lines
12 KiB
C++
/*=========================================================================
|
|
|
|
Program: ParaView
|
|
Module: vtkImageSliceRepresentation.cxx
|
|
|
|
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 "vtkImageSliceRepresentation.h"
|
|
|
|
#include "vtkCommand.h"
|
|
#include "vtkExtractVOI.h"
|
|
#include "vtkImageData.h"
|
|
#include "vtkImageVolumeRepresentation.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkMultiProcessController.h"
|
|
#include "vtkNew.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPExtentTranslator.h"
|
|
#include "vtkProperty.h"
|
|
#include "vtkPVCacheKeeper.h"
|
|
#include "vtkPVImageSliceMapper.h"
|
|
#include "vtkPVLODActor.h"
|
|
#include "vtkPVRenderView.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkStreamingDemandDrivenPipeline.h"
|
|
#include "vtkStructuredExtent.h"
|
|
|
|
#include <algorithm>
|
|
|
|
vtkStandardNewMacro(vtkImageSliceRepresentation);
|
|
//----------------------------------------------------------------------------
|
|
vtkImageSliceRepresentation::vtkImageSliceRepresentation()
|
|
{
|
|
this->Slice = 0;
|
|
this->SliceMode = XY_PLANE;
|
|
|
|
this->SliceData = vtkImageData::New();
|
|
this->CacheKeeper = vtkPVCacheKeeper::New();
|
|
this->CacheKeeper->SetInputData(this->SliceData);
|
|
|
|
this->SliceMapper = vtkPVImageSliceMapper::New();
|
|
this->Actor = vtkPVLODActor::New();
|
|
this->Actor->SetMapper(this->SliceMapper);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkImageSliceRepresentation::~vtkImageSliceRepresentation()
|
|
{
|
|
this->SliceData->Delete();
|
|
this->CacheKeeper->Delete();
|
|
this->SliceMapper->SetInputData(0);
|
|
this->SliceMapper->Delete();
|
|
this->Actor->Delete();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetSliceMode(int mode)
|
|
{
|
|
if (this->SliceMode != mode)
|
|
{
|
|
this->SliceMode = mode;
|
|
this->MarkModified();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetSlice(unsigned int val)
|
|
{
|
|
if (this->Slice != val)
|
|
{
|
|
this->Slice = val;
|
|
this->MarkModified();
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetInputArrayToProcess(
|
|
int idx, int port, int connection, int fieldAssociation, const char *name)
|
|
{
|
|
this->Superclass::SetInputArrayToProcess(
|
|
idx, port, connection, fieldAssociation, name);
|
|
this->SliceMapper->SelectColorArray(name);
|
|
switch (fieldAssociation)
|
|
{
|
|
case vtkDataObject::FIELD_ASSOCIATION_CELLS:
|
|
this->SliceMapper->SetScalarMode(VTK_SCALAR_MODE_USE_CELL_FIELD_DATA);
|
|
break;
|
|
|
|
case vtkDataObject::FIELD_ASSOCIATION_NONE:
|
|
this->SliceMapper->SetScalarMode(VTK_SCALAR_MODE_USE_FIELD_DATA);
|
|
// Color entire block by zeroth tuple in the field data
|
|
this->SliceMapper->SetFieldDataTupleId(0);
|
|
break;
|
|
|
|
case vtkDataObject::FIELD_ASSOCIATION_POINTS:
|
|
default:
|
|
this->SliceMapper->SetScalarMode(VTK_SCALAR_MODE_USE_POINT_FIELD_DATA);
|
|
break;
|
|
}
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkImageSliceRepresentation::FillInputPortInformation(
|
|
int, vtkInformation* info)
|
|
{
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkImageData");
|
|
info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkImageSliceRepresentation::ProcessViewRequest(
|
|
vtkInformationRequestKey* request_type,
|
|
vtkInformation* inInfo, vtkInformation* outInfo)
|
|
{
|
|
if (!this->Superclass::ProcessViewRequest(request_type, inInfo, outInfo))
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
if (request_type == vtkPVView::REQUEST_UPDATE())
|
|
{
|
|
// provide the "geometry" to the view so the view can delivery it to the
|
|
// rendering nodes as and when needed.
|
|
|
|
// When this process doesn't have any valid input, the cache-keeper is setup
|
|
// to provide a place-holder dataset of the right type.
|
|
vtkPVRenderView::SetPiece(inInfo, this,
|
|
this->CacheKeeper->GetOutputDataObject(0));
|
|
|
|
vtkImageData* img = vtkImageData::SafeDownCast(
|
|
this->CacheKeeper->GetOutputDataObject(0));
|
|
if (img)
|
|
{
|
|
vtkPVRenderView::SetGeometryBounds(inInfo, img->GetBounds());
|
|
}
|
|
|
|
// BUG #14253: support translucent rendering.
|
|
if (this->Actor->HasTranslucentPolygonalGeometry())
|
|
{
|
|
outInfo->Set(vtkPVRenderView::NEED_ORDERED_COMPOSITING(), 1);
|
|
if (img)
|
|
{
|
|
// Pass on the partitioning information to the view. This logic is similar
|
|
// to what we do in vtkImageVolumeRepresentation.
|
|
vtkPVRenderView::SetOrderedCompositingInformation(
|
|
inInfo, this, this->PExtentTranslator.GetPointer(),
|
|
this->WholeExtent, img->GetOrigin(), img->GetSpacing());
|
|
}
|
|
}
|
|
}
|
|
else if (request_type == vtkPVView::REQUEST_RENDER())
|
|
{
|
|
// since there's no direct connection between the mapper and the collector,
|
|
// we don't put an update-suppressor in the pipeline.
|
|
vtkAlgorithmOutput* producerPort = vtkPVRenderView::GetPieceProducer(inInfo, this);
|
|
if (producerPort)
|
|
{
|
|
this->SliceMapper->SetInputConnection(producerPort);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkImageSliceRepresentation::RequestData(vtkInformation* request,
|
|
vtkInformationVector** inputVector, vtkInformationVector* outputVector)
|
|
{
|
|
// Pass caching information to the cache keeper.
|
|
this->CacheKeeper->SetCachingEnabled(this->GetUseCache());
|
|
this->CacheKeeper->SetCacheTime(this->GetCacheKey());
|
|
|
|
if (inputVector[0]->GetNumberOfInformationObjects()==1)
|
|
{
|
|
this->UpdateSliceData(inputVector);
|
|
}
|
|
else
|
|
{
|
|
// This happens on the client in client-server mode. We simply mark the data
|
|
// dirty so that the "delivery" code can fetch new data.
|
|
if (!this->GetUsingCacheForUpdate())
|
|
{
|
|
this->SliceData->Modified();
|
|
}
|
|
}
|
|
this->CacheKeeper->Update();
|
|
|
|
return this->Superclass::RequestData(request, inputVector, outputVector);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkImageSliceRepresentation::IsCached(double cache_key)
|
|
{
|
|
return this->CacheKeeper->IsCached(cache_key);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::UpdateSliceData(
|
|
vtkInformationVector** inputVector)
|
|
{
|
|
if (this->GetUsingCacheForUpdate())
|
|
{
|
|
// FIXME: When using cache we're really using obsolete WholeExtent. We
|
|
// really need to cache WholeExtent information as well. See BUG 15899.
|
|
return;
|
|
}
|
|
|
|
vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkImageData* input = vtkImageData::GetData(inputVector[0], 0);
|
|
|
|
|
|
int inWholeExtent[6], outExt[6];
|
|
memset(outExt, 0, sizeof(int)*6);
|
|
|
|
inInfo->Get(vtkStreamingDemandDrivenPipeline::WHOLE_EXTENT(), inWholeExtent);
|
|
int dataDescription = vtkStructuredData::SetExtent(inWholeExtent, outExt);
|
|
|
|
std::copy(inWholeExtent, inWholeExtent+6, this->WholeExtent);
|
|
this->PExtentTranslator->GatherExtents(input);
|
|
|
|
if (vtkStructuredData::GetDataDimension(dataDescription) != 3)
|
|
{
|
|
this->SliceData->ShallowCopy(input);
|
|
return;
|
|
}
|
|
|
|
int dims[3];
|
|
dims[0] = inWholeExtent[1]-inWholeExtent[0]+1;
|
|
dims[1] = inWholeExtent[3]-inWholeExtent[2]+1;
|
|
dims[2] = inWholeExtent[5]-inWholeExtent[4]+1;
|
|
|
|
unsigned int slice = this->Slice;
|
|
switch (this->SliceMode)
|
|
{
|
|
case YZ_PLANE:
|
|
slice = (static_cast<int>(slice)>=dims[0])?dims[0]-1:slice;
|
|
outExt[0] = outExt[1] = outExt[0]+slice;
|
|
break;
|
|
|
|
case XZ_PLANE:
|
|
slice = (static_cast<int>(slice)>=dims[1])?dims[1]-1:slice;
|
|
outExt[2] = outExt[3] = outExt[2]+slice;
|
|
break;
|
|
|
|
case XY_PLANE:
|
|
default:
|
|
slice = (static_cast<int>(slice)>=dims[2])?dims[2]-1:slice;
|
|
outExt[4] = outExt[5] = outExt[4]+slice;
|
|
break;
|
|
}
|
|
|
|
// Now, clamp the extent for the slice to the extent available on this rank.
|
|
vtkNew<vtkStructuredExtent> helper;
|
|
helper->Clamp(outExt, input->GetExtent());
|
|
if (outExt[0] <= outExt[1] && outExt[2] <= outExt[3] && outExt[4] <= outExt[5])
|
|
{
|
|
vtkExtractVOI* voi = vtkExtractVOI::New();
|
|
voi->SetVOI(outExt);
|
|
voi->SetInputData(input);
|
|
voi->Update();
|
|
|
|
this->SliceData->ShallowCopy(voi->GetOutput());
|
|
voi->Delete();
|
|
}
|
|
else
|
|
{
|
|
this->SliceData->Initialize();
|
|
}
|
|
|
|
// vtkExtractVOI is not passing correct origin. Until that's fixed, I
|
|
// will just use the input origin/spacing to compute the bounds.
|
|
this->SliceData->SetOrigin(input->GetOrigin());
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkImageSliceRepresentation::AddToView(vtkView* view)
|
|
{
|
|
vtkPVRenderView* rview = vtkPVRenderView::SafeDownCast(view);
|
|
if (rview)
|
|
{
|
|
rview->GetRenderer()->AddActor(this->Actor);
|
|
return this->Superclass::AddToView(rview);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
bool vtkImageSliceRepresentation::RemoveFromView(vtkView* view)
|
|
{
|
|
vtkPVRenderView* rview = vtkPVRenderView::SafeDownCast(view);
|
|
if (rview)
|
|
{
|
|
rview->GetRenderer()->RemoveActor(this->Actor);
|
|
return this->Superclass::RemoveFromView(rview);
|
|
}
|
|
return false;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::MarkModified()
|
|
{
|
|
if (!this->GetUseCache())
|
|
{
|
|
// Cleanup caches when not using cache.
|
|
this->CacheKeeper->RemoveAllCaches();
|
|
}
|
|
this->Superclass::MarkModified();
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
}
|
|
|
|
//****************************************************************************
|
|
// Calls forwarded to internal objects.
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetOrientation(double x, double y, double z)
|
|
{
|
|
this->Actor->SetOrientation(x, y, z);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetOrigin(double x, double y, double z)
|
|
{
|
|
this->Actor->SetOrigin(x, y, z);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetPickable(int val)
|
|
{
|
|
this->Actor->SetPickable(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetPosition(double x, double y, double z)
|
|
{
|
|
this->Actor->SetPosition(x, y, z);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetScale(double x, double y, double z)
|
|
{
|
|
this->Actor->SetScale(x, y, z);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetVisibility(bool val)
|
|
{
|
|
this->Actor->SetVisibility(val? 1 : 0);
|
|
this->Superclass::SetVisibility(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetOpacity(double val)
|
|
{
|
|
this->Actor->GetProperty()->SetOpacity(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetLookupTable(vtkScalarsToColors* val)
|
|
{
|
|
this->SliceMapper->SetLookupTable(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetMapScalars(int val)
|
|
{
|
|
this->SliceMapper->SetColorMode(val);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkImageSliceRepresentation::SetUseXYPlane(int val)
|
|
{
|
|
this->SliceMapper->SetUseXYPlane(val);
|
|
}
|