You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
306 lines
9.4 KiB
306 lines
9.4 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkHierarchicalPolyDataMapper.cxx,v $
|
|
|
|
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 "vtkInformation.h"
|
|
#include "vtkMapper.h"
|
|
#include "vtkExecutive.h"
|
|
#include "vtkCompositeDataPipeline.h"
|
|
#include "vtkCompositeDataSet.h"
|
|
#include "vtkCompositeDataIterator.h"
|
|
#include "vtkHierarchicalDataSet.h"
|
|
#include "vtkPolyDataMapper.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkHierarchicalPolyDataMapper.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkGarbageCollector.h"
|
|
|
|
#include <vtkstd/vector>
|
|
|
|
vtkCxxRevisionMacro(vtkHierarchicalPolyDataMapper, "$Revision: 1.6 $");
|
|
vtkStandardNewMacro(vtkHierarchicalPolyDataMapper);
|
|
|
|
class vtkHierarchicalPolyDataMapperInternals
|
|
{
|
|
public:
|
|
vtkstd::vector<vtkPolyDataMapper*> Mappers;
|
|
};
|
|
|
|
vtkHierarchicalPolyDataMapper::vtkHierarchicalPolyDataMapper()
|
|
{
|
|
this->Internal = new vtkHierarchicalPolyDataMapperInternals;
|
|
}
|
|
|
|
vtkHierarchicalPolyDataMapper::~vtkHierarchicalPolyDataMapper()
|
|
{
|
|
for(unsigned int i=0;i<this->Internal->Mappers.size();i++)
|
|
{
|
|
this->Internal->Mappers[i]->UnRegister(this);
|
|
}
|
|
this->Internal->Mappers.clear();
|
|
|
|
delete this->Internal;
|
|
}
|
|
|
|
// Specify the type of data this mapper can handle. If we are
|
|
// working with a regular (not hierarchical) pipeline, then we
|
|
// need vtkPolyData. For composite data pipelines, then
|
|
// vtkHierarchicalDataSet is required, and we'll check when
|
|
// building our structure whether all the part of the composite
|
|
// data set are polydata.
|
|
int vtkHierarchicalPolyDataMapper::FillInputPortInformation(
|
|
int vtkNotUsed(port), vtkInformation* info)
|
|
{
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
|
|
info->Set(vtkCompositeDataPipeline::INPUT_REQUIRED_COMPOSITE_DATA_TYPE(),
|
|
"vtkHierarchicalDataSet");
|
|
return 1;
|
|
}
|
|
|
|
// When the structure is out-of-date, recreate it by
|
|
// creating a mapper for each input data.
|
|
void vtkHierarchicalPolyDataMapper::BuildPolyDataMapper()
|
|
{
|
|
int warnOnce = 0;
|
|
|
|
//Delete pdmappers if they already exist.
|
|
for(unsigned int i=0;i<this->Internal->Mappers.size();i++)
|
|
{
|
|
this->Internal->Mappers[i]->UnRegister(this);
|
|
}
|
|
this->Internal->Mappers.clear();
|
|
|
|
//Get the HierarchicalDataSet from the input
|
|
vtkInformation* inInfo = this->GetExecutive()->GetInputInformation(0,0);
|
|
vtkHierarchicalDataSet *input = vtkHierarchicalDataSet::SafeDownCast(
|
|
inInfo->Get(vtkCompositeDataSet::COMPOSITE_DATA_SET()));
|
|
|
|
// If it isn't hierarchical, maybe it is just a plain vtkPolyData
|
|
if(!input)
|
|
{
|
|
vtkPolyData *pd = vtkPolyData::SafeDownCast(
|
|
this->GetExecutive()->GetInputData(0, 0));
|
|
if ( pd )
|
|
{
|
|
// Make a copy of the data to break the pipeline here
|
|
vtkPolyData *newpd = vtkPolyData::New();
|
|
newpd->ShallowCopy(pd);
|
|
vtkPolyDataMapper *pdmapper = vtkPolyDataMapper::New();
|
|
pdmapper->Register( this );
|
|
pdmapper->SetInput(newpd);
|
|
this->Internal->Mappers.push_back(pdmapper);
|
|
newpd->Delete();
|
|
pdmapper->Delete();
|
|
}
|
|
}
|
|
else
|
|
{
|
|
//for each data set build a vtkPolyDataMapper
|
|
vtkCompositeDataIterator* iter = input->NewIterator();
|
|
iter->GoToFirstItem();
|
|
while (!iter->IsDoneWithTraversal())
|
|
{
|
|
vtkPolyData* pd = vtkPolyData::SafeDownCast(iter->GetCurrentDataObject());
|
|
if (pd)
|
|
{
|
|
// Make a copy of the data to break the pipeline here
|
|
vtkPolyData *newpd = vtkPolyData::New();
|
|
newpd->ShallowCopy(pd);
|
|
vtkPolyDataMapper *pdmapper = vtkPolyDataMapper::New();
|
|
pdmapper->Register(this);
|
|
pdmapper->SetInput(newpd);
|
|
this->Internal->Mappers.push_back(pdmapper);
|
|
newpd->Delete();
|
|
pdmapper->Delete();
|
|
}
|
|
// This is not polydata - warn the user that there are non-polydata
|
|
// parts to this data set which will not be rendered by this mapper
|
|
else
|
|
{
|
|
if ( !warnOnce )
|
|
{
|
|
vtkErrorMacro("All data in the hierachical dataset must be polydata.");
|
|
warnOnce = 1;
|
|
}
|
|
}
|
|
iter->GoToNextItem();
|
|
}
|
|
iter->Delete();
|
|
}
|
|
|
|
this->InternalMappersBuildTime.Modified();
|
|
|
|
}
|
|
|
|
void vtkHierarchicalPolyDataMapper::Render(vtkRenderer *ren, vtkActor *a)
|
|
{
|
|
//If the PolyDataMappers are not up-to-date then rebuild them
|
|
vtkCompositeDataPipeline * executive =
|
|
vtkCompositeDataPipeline::SafeDownCast(this->GetExecutive());
|
|
|
|
if(executive->GetPipelineMTime() > this->InternalMappersBuildTime.GetMTime())
|
|
{
|
|
this->BuildPolyDataMapper();
|
|
}
|
|
|
|
this->TimeToDraw = 0;
|
|
//Call Render() on each of the PolyDataMappers
|
|
for(unsigned int i=0;i<this->Internal->Mappers.size();i++)
|
|
{
|
|
if ( this->ClippingPlanes !=
|
|
this->Internal->Mappers[i]->GetClippingPlanes() )
|
|
{
|
|
this->Internal->Mappers[i]->SetClippingPlanes( this->ClippingPlanes );
|
|
}
|
|
|
|
this->Internal->Mappers[i]->SetLookupTable(
|
|
this->GetLookupTable());
|
|
this->Internal->Mappers[i]->SetScalarVisibility(
|
|
this->GetScalarVisibility());
|
|
this->Internal->Mappers[i]->SetUseLookupTableScalarRange(
|
|
this->GetUseLookupTableScalarRange());
|
|
this->Internal->Mappers[i]->SetScalarRange(
|
|
this->GetScalarRange());
|
|
this->Internal->Mappers[i]->SetImmediateModeRendering(
|
|
this->GetImmediateModeRendering());
|
|
this->Internal->Mappers[i]->SetColorMode(this->GetColorMode());
|
|
this->Internal->Mappers[i]->SetInterpolateScalarsBeforeMapping(
|
|
this->GetInterpolateScalarsBeforeMapping());
|
|
|
|
this->Internal->Mappers[i]->SetScalarMode(this->GetScalarMode());
|
|
if ( this->ScalarMode == VTK_SCALAR_MODE_USE_POINT_FIELD_DATA ||
|
|
this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA )
|
|
{
|
|
if ( this->ArrayAccessMode == VTK_GET_ARRAY_BY_ID )
|
|
{
|
|
this->Internal->Mappers[i]->ColorByArrayComponent(
|
|
this->ArrayId,ArrayComponent);
|
|
}
|
|
else
|
|
{
|
|
this->Internal->Mappers[i]->ColorByArrayComponent(
|
|
this->ArrayName,ArrayComponent);
|
|
}
|
|
}
|
|
|
|
this->Internal->Mappers[i]->Render(ren,a);
|
|
this->TimeToDraw += this->Internal->Mappers[i]->GetTimeToDraw();
|
|
}
|
|
}
|
|
vtkExecutive* vtkHierarchicalPolyDataMapper::CreateDefaultExecutive()
|
|
{
|
|
return vtkCompositeDataPipeline::New();
|
|
}
|
|
|
|
//Looks at each DataSet and finds the union of all the bounds
|
|
void vtkHierarchicalPolyDataMapper::ComputeBounds()
|
|
{
|
|
vtkMath::UninitializeBounds(this->Bounds);
|
|
|
|
vtkInformation* inInfo = this->GetExecutive()->GetInputInformation(0,0);
|
|
vtkHierarchicalDataSet *input = vtkHierarchicalDataSet::SafeDownCast(
|
|
inInfo->Get(vtkCompositeDataSet::COMPOSITE_DATA_SET()));
|
|
|
|
// If we don't have hierarchical data, test to see if we have
|
|
// plain old polydata. In this case, the bounds are simply
|
|
// the bounds of the input polydata.
|
|
if(!input)
|
|
{
|
|
vtkPolyData *pd = vtkPolyData::SafeDownCast(
|
|
this->GetExecutive()->GetInputData(0, 0));
|
|
if ( pd )
|
|
{
|
|
pd->GetBounds( this->Bounds );
|
|
}
|
|
return;
|
|
}
|
|
|
|
// We do have hierarchical data - so we need to loop over
|
|
// it and get the total bounds.
|
|
vtkCompositeDataIterator* iter = input->NewIterator();
|
|
iter->GoToFirstItem();
|
|
double bounds[6];
|
|
int i;
|
|
|
|
while (!iter->IsDoneWithTraversal())
|
|
{
|
|
vtkPolyData *pd = vtkPolyData::SafeDownCast(iter->GetCurrentDataObject());
|
|
if (pd)
|
|
{
|
|
// If this isn't the first time through, expand bounds
|
|
// we've compute so far based on the bounds of this
|
|
// block
|
|
if ( vtkMath::AreBoundsInitialized(this->Bounds) )
|
|
{
|
|
pd->GetBounds(bounds);
|
|
for(i=0; i<3; i++)
|
|
{
|
|
this->Bounds[i*2] =
|
|
(bounds[i*2]<this->Bounds[i*2])?
|
|
(bounds[i*2]):(this->Bounds[i*2]);
|
|
this->Bounds[i*2+1] =
|
|
(bounds[i*2+1]>this->Bounds[i*2+1])?
|
|
(bounds[i*2+1]):(this->Bounds[i*2+1]);
|
|
}
|
|
}
|
|
// If this is our first time through, just get the bounds
|
|
// of the data as the initial bounds
|
|
else
|
|
{
|
|
pd->GetBounds(this->Bounds);
|
|
}
|
|
}
|
|
iter->GoToNextItem();
|
|
}
|
|
iter->Delete();
|
|
this->BoundsMTime.Modified();
|
|
}
|
|
|
|
double* vtkHierarchicalPolyDataMapper::GetBounds()
|
|
{
|
|
static double bounds[] = {-1.0,1.0, -1.0,1.0, -1.0,1.0};
|
|
|
|
if ( ! this->GetInput() )
|
|
{
|
|
return bounds;
|
|
}
|
|
else
|
|
{
|
|
|
|
this->Update();
|
|
|
|
//only compute bounds when the input data has changed
|
|
vtkCompositeDataPipeline * executive = vtkCompositeDataPipeline::SafeDownCast(this->GetExecutive());
|
|
if( executive->GetPipelineMTime() > this->BoundsMTime.GetMTime() )
|
|
{
|
|
ComputeBounds();
|
|
}
|
|
|
|
return this->Bounds;
|
|
}
|
|
}
|
|
|
|
void vtkHierarchicalPolyDataMapper::ReleaseGraphicsResources( vtkWindow *win )
|
|
{
|
|
for(unsigned int i=0;i<this->Internal->Mappers.size();i++)
|
|
{
|
|
this->Internal->Mappers[i]->ReleaseGraphicsResources( win );
|
|
}
|
|
}
|
|
|
|
void vtkHierarchicalPolyDataMapper::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
}
|
|
|