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.
nmWTAI-Platform/3rd/VTK7.1/source/VTK-7.1.1/Rendering/OpenGL/vtkPainter.cxx

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;
}
}