Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

379 lines
9.7 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkLODActor.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 "vtkLODActor.h"
#include "vtkMapperCollection.h"
#include "vtkMaskPoints.h"
#include "vtkMatrix4x4.h"
#include "vtkObjectFactory.h"
#include "vtkOutlineFilter.h"
#include "vtkPolyDataMapper.h"
#include "vtkProperty.h"
#include "vtkRenderWindow.h"
#include "vtkRenderer.h"
#include "vtkTexture.h"
#include "vtkTimerLog.h"
#include <math.h>
vtkCxxRevisionMacro(vtkLODActor, "$Revision: 1.66 $");
vtkStandardNewMacro(vtkLODActor);
//----------------------------------------------------------------------------
vtkLODActor::vtkLODActor()
{
vtkMatrix4x4 *m;
// get a hardware dependent actor and mappers
this->Device = vtkActor::New();
m = vtkMatrix4x4::New();
this->Device->SetUserMatrix(m);
m->Delete();
this->LODMappers = vtkMapperCollection::New();
// stuff for creating own LODs
this->MaskPoints = NULL;
this->OutlineFilter = NULL;
this->NumberOfCloudPoints = 150;
this->LowMapper = NULL;
this->MediumMapper = NULL;
}
//----------------------------------------------------------------------------
vtkLODActor::~vtkLODActor()
{
this->Device->Delete();
this->DeleteOwnLODs();
this->LODMappers->Delete();
}
//----------------------------------------------------------------------------
void vtkLODActor::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "Cloud Points: " << this->NumberOfCloudPoints << endl;
// how should we print out the LODMappers?
os << indent << "Number Of LOD Mappers: "
<< this->LODMappers->GetNumberOfItems() << endl;
}
//----------------------------------------------------------------------------
void vtkLODActor::Render(vtkRenderer *ren, vtkMapper *vtkNotUsed(m))
{
float myTime, bestTime, tempTime;
vtkMatrix4x4 *matrix;
vtkMapper *mapper, *bestMapper;
if (this->Mapper == NULL)
{
vtkErrorMacro("No mapper for actor.");
return;
}
// first time through create lods if non have been added
if (this->LODMappers->GetNumberOfItems() == 0)
{
this->CreateOwnLODs();
}
// If the actor has changed or the primary mapper has changed ...
// Is this the correct test?
if (this->MediumMapper)
{
if (this->GetMTime() > this->BuildTime ||
this->Mapper->GetMTime() > this->BuildTime)
{
this->UpdateOwnLODs();
}
}
// figure out how much time we have to render
myTime = this->AllocatedRenderTime;
// Figure out which resolution to use
// none is a valid resolution. Do we want to have a lowest:
// bbox, single point, ...
// There is no order to the list, so it is assumed that mappers that take
// longer to render are better quality.
// Timings might become out of date, but we rely on
bestMapper = this->Mapper;
bestTime = bestMapper->GetTimeToDraw();
if (bestTime > myTime)
{
vtkCollectionSimpleIterator mit;
this->LODMappers->InitTraversal(mit);
while ((mapper = this->LODMappers->GetNextMapper(mit)) != NULL &&
bestTime != 0.0)
{
tempTime = mapper->GetTimeToDraw();
// If the LOD has never been rendered, select it!
if (tempTime == 0.0)
{
bestMapper = mapper;
bestTime = 0.0;
}
else
{
if (bestTime > myTime && tempTime < bestTime)
{
bestMapper = mapper;
bestTime = tempTime;
}
if (tempTime > bestTime && tempTime < myTime)
{
bestMapper = mapper;
bestTime = tempTime;
}
}
}
}
// render the property
if (!this->Property)
{
// force creation of a property
this->GetProperty();
}
this->Property->Render(this, ren);
if (this->BackfaceProperty)
{
this->BackfaceProperty->BackfaceRender(this, ren);
this->Device->SetBackfaceProperty(this->BackfaceProperty);
}
this->Device->SetProperty(this->Property);
// render the texture
if (this->Texture)
{
this->Texture->Render(ren);
}
// make sure the device has the same matrix
matrix = this->Device->GetUserMatrix();
this->GetMatrix(matrix);
// Store information on time it takes to render.
// We might want to estimate time from the number of polygons in mapper.
this->Device->Render(ren,bestMapper);
this->EstimatedRenderTime = bestMapper->GetTimeToDraw();
}
int vtkLODActor::RenderOpaqueGeometry(vtkViewport *vp)
{
int renderedSomething = 0;
vtkRenderer* ren = static_cast<vtkRenderer*>(vp);
if ( ! this->Mapper )
{
return 0;
}
// make sure we have a property
if (!this->Property)
{
// force creation of a property
this->GetProperty();
}
// is this actor opaque ?
if (this->GetIsOpaque())
{
this->Property->Render(this, ren);
// render the backface property
if (this->BackfaceProperty)
{
this->BackfaceProperty->BackfaceRender(this, ren);
}
// render the texture
if (this->Texture)
{
this->Texture->Render(ren);
}
this->Render(ren,this->Mapper);
renderedSomething = 1;
}
return renderedSomething;
}
void vtkLODActor::ReleaseGraphicsResources(vtkWindow *renWin)
{
vtkMapper *mapper;
vtkActor::ReleaseGraphicsResources(renWin);
// broadcast the message down to the individual LOD mappers
vtkCollectionSimpleIterator mit;
for ( this->LODMappers->InitTraversal(mit);
(mapper = this->LODMappers->GetNextMapper(mit)); )
{
mapper->ReleaseGraphicsResources(renWin);
}
}
//----------------------------------------------------------------------------
// does not matter if mapper is in mapper collection.
void vtkLODActor::AddLODMapper(vtkMapper *mapper)
{
if (this->MediumMapper)
{
this->DeleteOwnLODs();
}
if (this->Mapper == NULL)
{
this->SetMapper(mapper);
}
this->LODMappers->AddItem(mapper);
}
//----------------------------------------------------------------------------
// Can only be used if no LOD mappers have been added.
// Maybe we should remove this exculsive feature.
void vtkLODActor::CreateOwnLODs()
{
if (this->MediumMapper)
{
return;
}
if ( this->Mapper == NULL)
{
vtkErrorMacro("Cannot create LODs with out a mapper.");
return;
}
// There are ways of getting arround this limitation ...
if ( this->LODMappers->GetNumberOfItems() > 0 )
{
vtkErrorMacro(<<
"Cannot generate LOD mappers when some have been added already");
return;
}
// create filters and mappers
this->MaskPoints = vtkMaskPoints::New();
this->MaskPoints->RandomModeOn();
this->MaskPoints->GenerateVerticesOn();
this->MediumMapper = vtkPolyDataMapper::New();
this->OutlineFilter = vtkOutlineFilter::New();
this->LowMapper = vtkPolyDataMapper::New();
this->LODMappers->AddItem(this->MediumMapper);
this->LODMappers->AddItem(this->LowMapper);
this->UpdateOwnLODs();
}
//----------------------------------------------------------------------------
void vtkLODActor::UpdateOwnLODs()
{
if ( this->Mapper == NULL)
{
vtkErrorMacro("Cannot create LODs with out a mapper.");
return;
}
if (this->MediumMapper == NULL)
{
this->CreateOwnLODs();
if (this->MediumMapper == NULL)
{ // could not create the LODs
return;
}
}
// connect the filters to the mapper, and set parameters
this->MaskPoints->SetInput(this->Mapper->GetInput());
this->MaskPoints->SetMaximumNumberOfPoints(this->NumberOfCloudPoints);
this->OutlineFilter->SetInput(this->Mapper->GetInput());
// copy all parameters including LUTs, scalar range, etc.
this->MediumMapper->ShallowCopy(this->Mapper);
this->MediumMapper->SetInput(this->MaskPoints->GetOutput());
this->LowMapper->ShallowCopy(this->Mapper);
this->LowMapper->ScalarVisibilityOff();
this->LowMapper->SetInput(this->OutlineFilter->GetOutput());
this->BuildTime.Modified();
}
//----------------------------------------------------------------------------
// Deletes Mappers and filters created by this object.
// (number two and three)
void vtkLODActor::DeleteOwnLODs()
{
if (this->MediumMapper == NULL)
{
return;
}
// remove the mappers from the LOD collection
this->LODMappers->RemoveItem(this->LowMapper);
this->LODMappers->RemoveItem(this->MediumMapper);
// delete the filters used to create the LODs ...
// The NULL check should not be necessary, but for sanity ...
this->MaskPoints->Delete();
this->MaskPoints = NULL;
this->OutlineFilter->Delete();
this->OutlineFilter = NULL;
this->LowMapper->Delete();
this->LowMapper = NULL;
this->MediumMapper->Delete();
this->MediumMapper = NULL;
}
//----------------------------------------------------------------------------
void vtkLODActor::Modified()
{
this->Device->Modified();
this->vtkActor::Modified();
}
void vtkLODActor::ShallowCopy(vtkProp *prop)
{
vtkLODActor *a = vtkLODActor::SafeDownCast(prop);
if ( a != NULL )
{
this->SetNumberOfCloudPoints(a->GetNumberOfCloudPoints());
vtkMapperCollection *c = a->GetLODMappers();
vtkMapper *map;
vtkCollectionSimpleIterator mit;
for ( c->InitTraversal(mit); (map=c->GetNextMapper(mit)); )
{
this->AddLODMapper(map);
}
}
// Now do superclass
this->vtkActor::ShallowCopy(prop);
}