You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
370 lines
10 KiB
C++
370 lines
10 KiB
C++
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: vtkPainter.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.
|
|
|
|
=========================================================================*/
|
|
|
|
/*
|
|
* Copyright 2004 Sandia Corporation.
|
|
* Under the terms of Contract DE-AC04-94AL85000, there is a non-exclusive
|
|
* license for use of this work by or on behalf of the
|
|
* U.S. Government. Redistribution and use in source and binary forms, with
|
|
* or without modification, are permitted provided that this Notice and any
|
|
* statement of authorship are reproduced on all copies.
|
|
*/
|
|
|
|
#include "vtkPainter.h"
|
|
|
|
#include "vtkCellData.h"
|
|
#include "vtkCommand.h"
|
|
#include "vtkDataSet.h"
|
|
#include "vtkDebugLeaks.h"
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationIntegerKey.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkRenderer.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkTimerLog.h"
|
|
|
|
vtkCxxSetObjectMacro(vtkPainter, Input, vtkDataObject);
|
|
vtkCxxSetObjectMacro(vtkPainter, Information, vtkInformation);
|
|
vtkInformationKeyMacro(vtkPainter, STATIC_DATA, Integer);
|
|
vtkInformationKeyMacro(vtkPainter, CONSERVE_MEMORY, Integer);
|
|
vtkInformationKeyMacro(vtkPainter, HIGH_QUALITY, Integer);
|
|
//-----------------------------------------------------------------------------
|
|
class vtkPainterObserver : public vtkCommand
|
|
{
|
|
public:
|
|
static vtkPainterObserver* New()
|
|
{ return new vtkPainterObserver; }
|
|
|
|
virtual void Execute(vtkObject *caller,
|
|
unsigned long event, void* vtkNotUsed(v))
|
|
{
|
|
vtkPainter* delegate = vtkPainter::SafeDownCast(caller);
|
|
if (delegate && event == vtkCommand::ProgressEvent && this->Self)
|
|
{
|
|
this->Self->UpdateDelegateProgress(delegate, delegate->GetProgress());
|
|
}
|
|
}
|
|
|
|
vtkPainter* Self;
|
|
};
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPainter::vtkPainter()
|
|
{
|
|
this->Input = 0;
|
|
this->DelegatePainter = NULL;
|
|
this->LastWindow = 0;
|
|
|
|
this->Progress = 0.0;
|
|
this->ProgressOffset = 0.0;
|
|
this->ProgressScaleFactor = 1.0;
|
|
|
|
this->Observer = vtkPainterObserver::New();
|
|
this->Observer->Self = this;
|
|
|
|
this->TimeToDraw = 0.0;
|
|
this->Timer = vtkTimerLog::New();
|
|
|
|
this->Information = NULL;
|
|
vtkInformation* temp = vtkInformation::New();
|
|
this->SetInformation(temp);
|
|
temp->Delete();
|
|
|
|
vtkPainter::STATIC_DATA()->Set(this->Information, 0);
|
|
vtkPainter::CONSERVE_MEMORY()->Set(this->Information, 0);
|
|
vtkPainter::HIGH_QUALITY()->Set(this->Information, 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
vtkPainter::~vtkPainter()
|
|
{
|
|
this->SetInput(0);
|
|
this->Observer->Self = NULL;
|
|
this->Observer->Delete();
|
|
|
|
this->SetDelegatePainter(NULL);
|
|
this->SetInformation(NULL);
|
|
|
|
if (this->LastWindow)
|
|
{
|
|
this->ReleaseGraphicsResources(this->LastWindow);
|
|
this->LastWindow = 0;
|
|
}
|
|
|
|
this->Timer->Delete();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::UpdateProgress(double amount)
|
|
{
|
|
this->Progress = amount;
|
|
this->InvokeEvent(vtkCommand::ProgressEvent,
|
|
reinterpret_cast<void *>(&amount));
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::UpdateDelegateProgress(vtkPainter* vtkNotUsed(delegate),
|
|
double amount)
|
|
{
|
|
double scaled_amount = this->ProgressOffset +
|
|
this->ProgressScaleFactor * amount;
|
|
this->UpdateProgress(scaled_amount);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
double vtkPainter::GetTimeToDraw()
|
|
{
|
|
double time = this->TimeToDraw;
|
|
if (this->DelegatePainter)
|
|
{
|
|
time += this->DelegatePainter->GetTimeToDraw();
|
|
}
|
|
return time;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::ReleaseGraphicsResources(vtkWindow *w)
|
|
{
|
|
if (this->DelegatePainter)
|
|
{
|
|
this->DelegatePainter->ReleaseGraphicsResources(w);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::Register(vtkObjectBase *o)
|
|
{
|
|
this->RegisterInternal(o, 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::UnRegister(vtkObjectBase *o)
|
|
{
|
|
this->UnRegisterInternal(o, 1);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::SetDelegatePainter(vtkPainter* delegate)
|
|
{
|
|
if (this->DelegatePainter)
|
|
{
|
|
this->DelegatePainter->RemoveObserver(this->Observer);
|
|
}
|
|
|
|
vtkSetObjectBodyMacro(DelegatePainter, vtkPainter, delegate);
|
|
|
|
if (this->DelegatePainter)
|
|
{
|
|
this->ObserverPainterProgress(this->DelegatePainter);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::ObserverPainterProgress(vtkPainter* p)
|
|
{
|
|
p->AddObserver(vtkCommand::ProgressEvent, this->Observer);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::ReportReferences(vtkGarbageCollector *collector)
|
|
{
|
|
this->Superclass::ReportReferences(collector);
|
|
vtkGarbageCollectorReport(collector, this->DelegatePainter,
|
|
"Delegate Painter");
|
|
vtkGarbageCollectorReport(collector, this->Input, "Input");
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::Render(vtkRenderer* renderer, vtkActor* actor,
|
|
unsigned long typeflags, bool forceCompileOnly)
|
|
{
|
|
this->TimeToDraw = 0.0;
|
|
if (renderer->GetRenderWindow()->CheckAbortStatus())
|
|
{
|
|
return;
|
|
}
|
|
|
|
if (this->InformationProcessTime < this->Information->GetMTime())
|
|
{
|
|
// If the information object was modified, some subclass may
|
|
// want to get the modified information.
|
|
// Using ProcessInformation avoids the need to access the Information
|
|
// object during each render, thus reducing unnecessary
|
|
// expensive information key accesses.
|
|
this->ProcessInformation(this->Information);
|
|
this->InformationProcessTime.Modified();
|
|
}
|
|
|
|
this->PrepareForRendering(renderer, actor);
|
|
this->RenderInternal(renderer, actor, typeflags,forceCompileOnly);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::RenderInternal(vtkRenderer* renderer, vtkActor* actor,
|
|
unsigned long typeflags, bool forceCompileOnly)
|
|
{
|
|
if (this->DelegatePainter)
|
|
{
|
|
this->UpdateDelegatePainter();
|
|
this->DelegatePainter->Render(renderer, actor, typeflags,forceCompileOnly);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::UpdateDelegatePainter()
|
|
{
|
|
this->PassInformation(this->DelegatePainter);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::PassInformation(vtkPainter* toPainter)
|
|
{
|
|
/*
|
|
if (this->Information->GetMTime() >
|
|
toPainter->GetInformation()->GetMTime())
|
|
{
|
|
// We have updated information, pass it on to
|
|
// the delegate.
|
|
// We do a shallow copy.
|
|
toPainter->GetInformation()->Copy(this->Information);
|
|
}
|
|
*/
|
|
// TODO: I can't decide if the information must be copied
|
|
// or referenced.
|
|
if (this->Information != toPainter->GetInformation())
|
|
{
|
|
// We have updated information, pass it on to
|
|
// the delegate.
|
|
toPainter->SetInformation(this->Information);
|
|
}
|
|
|
|
// Propagate the data object through the painter chain.
|
|
vtkDataObject* myoutput = this->GetOutput();
|
|
if (myoutput != toPainter->GetInput())
|
|
{
|
|
toPainter->SetInput(myoutput);
|
|
}
|
|
}
|
|
|
|
//-------------------------------------------------------------------------
|
|
void vtkPainter::UpdateBounds(double bounds[6])
|
|
{
|
|
// only apply UpdateBounds on the delegate painter
|
|
vtkPainter *painter = this->GetDelegatePainter();
|
|
|
|
if(painter)
|
|
{
|
|
// delegate the task of updating the bounds
|
|
painter->UpdateBounds(bounds);
|
|
}
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Description:
|
|
// Helper method to get input array to process.
|
|
vtkAbstractArray* vtkPainter::GetInputArrayToProcess(int fieldAssociation,
|
|
int fieldAttributeType,
|
|
vtkDataSet* inputDS,
|
|
bool *use_cell_data)
|
|
{
|
|
if (use_cell_data)
|
|
{
|
|
*use_cell_data = false;
|
|
}
|
|
if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
|
|
{
|
|
return inputDS->GetPointData()->GetAbstractAttribute(fieldAttributeType);
|
|
}
|
|
|
|
if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS)
|
|
{
|
|
vtkAbstractArray* array =
|
|
inputDS->GetPointData()->GetAbstractAttribute(fieldAttributeType);
|
|
if (array)
|
|
{
|
|
return array;
|
|
}
|
|
}
|
|
|
|
if (use_cell_data)
|
|
{
|
|
*use_cell_data = true;
|
|
}
|
|
return inputDS->GetCellData()->GetAbstractAttribute(fieldAttributeType);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Description:
|
|
// Helper method to get input array to process.
|
|
vtkAbstractArray* vtkPainter::GetInputArrayToProcess(int fieldAssociation,
|
|
const char* name, vtkDataSet* inputDS, bool *use_cell_data)
|
|
{
|
|
if (use_cell_data)
|
|
{
|
|
*use_cell_data = false;
|
|
}
|
|
if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS)
|
|
{
|
|
return inputDS->GetPointData()->GetAbstractArray(name);
|
|
}
|
|
|
|
if (fieldAssociation == vtkDataObject::FIELD_ASSOCIATION_POINTS_THEN_CELLS)
|
|
{
|
|
vtkAbstractArray* array =
|
|
inputDS->GetPointData()->GetAbstractArray(name);
|
|
if (array)
|
|
{
|
|
return array;
|
|
}
|
|
}
|
|
|
|
if (use_cell_data)
|
|
{
|
|
*use_cell_data = true;
|
|
}
|
|
return inputDS->GetCellData()->GetAbstractArray(name);
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void vtkPainter::PrintSelf(ostream &os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os, indent);
|
|
os << indent << "Input: " << this->Input << endl;
|
|
os << indent << "TimeToDraw: " << this->TimeToDraw << endl;
|
|
os << indent << "Progress: " << this->Progress << endl;
|
|
os << indent << "Information: " ;
|
|
if (this->Information)
|
|
{
|
|
os << endl;
|
|
this->Information->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
|
|
os << indent << "DelegatePainter: " ;
|
|
if (this->DelegatePainter)
|
|
{
|
|
os << endl;
|
|
this->DelegatePainter->PrintSelf(os, indent.GetNextIndent());
|
|
}
|
|
else
|
|
{
|
|
os << "(none)" << endl;
|
|
}
|
|
}
|