VTK/Examples/Developers/vtkAlgorithm Source Multiple Output Ports

From KitwarePublic

Jump to: navigation, search

This example demonstrates how to setup a source that produces two outputs. The output on port 0 is of type vtkTestA and the Value gets set to 111. The output on port 1 is of type vtkTestB and the Value gets set to 222.

Contents

vtkAlgorithmSourceMultiplePortsExample.cxx

#include <vtkSmartPointer.h>
 
#include "vtkTestSource.h"
#include "vtkTestA.h"
#include "vtkTestB.h"
 
int main (int argc, char *argv[])
{
  vtkTestSource* source = vtkTestSource::New();
  source->Update();
 
  vtkTestA* testa = source->GetOutputA();
  vtkTestB* testb = source->GetOutputB();
 
  std::cout << testa->GetValue() << std::endl;
 
  std::cout << testb->GetValue() << std::endl;
 
  return EXIT_SUCCESS;
}

vtkTestSource.h

#ifndef __vtkTestSource_h
#define __vtkTestSource_h
 
#include "vtkAlgorithm.h"
 
class vtkDataSet;
class vtkTestA;
class vtkTestB;
 
class vtkTestSource : public vtkAlgorithm
{
  public:
    static vtkTestSource *New();
    vtkTypeRevisionMacro(vtkTestSource,vtkAlgorithm);
    void PrintSelf(ostream& os, vtkIndent indent);
 
  // Description:
  // Get the output data object for a port on this algorithm.
    vtkTestA* GetOutputA();
    vtkTestB* GetOutputB();
 
    virtual void SetOutput(vtkDataObject* d);
 
  // Description:
  // see vtkAlgorithm for details
    virtual int ProcessRequest(vtkInformation*,
                               vtkInformationVector**,
                               vtkInformationVector*);
 
  protected:
    vtkTestSource();
    ~vtkTestSource();
 
  // Description:
  // This is called by the superclass.
  // This is the method you should override.
    virtual int RequestDataObject(
                                  vtkInformation* request,
                                  vtkInformationVector** inputVector,
                                  vtkInformationVector* outputVector );
 
  // convenience method
    virtual int RequestInformation(
                                   vtkInformation* request,
                                   vtkInformationVector** inputVector,
                                   vtkInformationVector* outputVector );
 
  // Description:
  // This is called by the superclass.
  // This is the method you should override.
    virtual int RequestData(
                            vtkInformation* request,
                            vtkInformationVector** inputVector,
                            vtkInformationVector* outputVector );
 
  // Description:
  // This is called by the superclass.
  // This is the method you should override.
    virtual int RequestUpdateExtent(
                                    vtkInformation*,
                                    vtkInformationVector**,
                                    vtkInformationVector* );
 
    virtual int FillOutputPortInformation( int port, vtkInformation* info );
 
  private:
    vtkTestSource( const vtkTestSource& ); // Not implemented.
    void operator = ( const vtkTestSource& );  // Not implemented.
 
};
 
#endif

vtkTestSource.cxx

#include "vtkTestSource.h"
#include "vtkTestA.h"
#include "vtkTestB.h"
 
#include "vtkCommand.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkStreamingDemandDrivenPipeline.h"
 
vtkCxxRevisionMacro(vtkTestSource, "$Revision: 1.1 $");
vtkStandardNewMacro(vtkTestSource);
 
//----------------------------------------------------------------------------
vtkTestSource::vtkTestSource()
{
  this->SetNumberOfInputPorts( 0 );
  this->SetNumberOfOutputPorts( 2 );
}
 
//----------------------------------------------------------------------------
vtkTestSource::~vtkTestSource()
{
}
 
//----------------------------------------------------------------------------
void vtkTestSource::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}
 
//----------------------------------------------------------------------------
vtkTestA* vtkTestSource::GetOutputA()
{
  return vtkTestA::SafeDownCast(this->GetOutputDataObject(0));
}
 
//----------------------------------------------------------------------------
vtkTestB* vtkTestSource::GetOutputB()
{
  return vtkTestB::SafeDownCast(this->GetOutputDataObject(1));
}
 
 
//----------------------------------------------------------------------------
void vtkTestSource::SetOutput(vtkDataObject* d)
{
  this->GetExecutive()->SetOutputData(0, d);
}
 
 
//----------------------------------------------------------------------------
int vtkTestSource::ProcessRequest(vtkInformation* request,
                                     vtkInformationVector** inputVector,
                                     vtkInformationVector* outputVector)
{
  // Create an output object of the correct type.
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA_OBJECT()))
  {
    return this->RequestDataObject(request, inputVector, outputVector);
  }
  // generate the data
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
  {
    return this->RequestData(request, inputVector, outputVector);
  }
 
  if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
  {
    return this->RequestUpdateExtent(request, inputVector, outputVector);
  }
 
  // execute information
  if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
  {
    return this->RequestInformation(request, inputVector, outputVector);
  }
 
  return this->Superclass::ProcessRequest(request, inputVector, outputVector);
}
 
//----------------------------------------------------------------------------
int vtkTestSource::FillOutputPortInformation(int port, vtkInformation* info)
{
  // now add our info
  if(port == 0)
    {
    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTestA");
    }
  else if(port == 1)
    {
    info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkTestB");
    }
 
  return 1;
}
 
 
//----------------------------------------------------------------------------
int vtkTestSource::RequestDataObject(
                                        vtkInformation* vtkNotUsed(request),
    vtkInformationVector** vtkNotUsed(inputVector),
                                      vtkInformationVector* outputVector )
{
  //output 0 - TestA
  vtkInformation* outInfoA = outputVector->GetInformationObject(0);
  vtkTestA* outputA = vtkTestA::SafeDownCast(
                                          outInfoA->Get( vtkDataObject::DATA_OBJECT() ) );
  if ( ! outputA )
  {
    outputA = vtkTestA::New();
    outInfoA->Set( vtkDataObject::DATA_OBJECT(), outputA );
    outputA->FastDelete();
    outputA->SetPipelineInformation( outInfoA );
    this->GetOutputPortInformation(0)->Set(
                                    vtkDataObject::DATA_EXTENT_TYPE(), outputA->GetExtentType() );
  }
 
  //output 1 - TestB
  vtkInformation* outInfoB = outputVector->GetInformationObject(1);
  vtkTestB* outputB = vtkTestB::SafeDownCast(
                                              outInfoB->Get( vtkDataObject::DATA_OBJECT() ) );
  if ( ! outputB )
  {
    outputB = vtkTestB::New();
    outInfoB->Set( vtkDataObject::DATA_OBJECT(), outputB );
    outputB->FastDelete();
    outputB->SetPipelineInformation( outInfoB );
    this->GetOutputPortInformation(1)->Set(
                                    vtkDataObject::DATA_EXTENT_TYPE(), outputB->GetExtentType() );
  }
 
  return 1;
}
 
//----------------------------------------------------------------------------
int vtkTestSource::RequestInformation(
                                         vtkInformation* vtkNotUsed(request),
    vtkInformationVector** vtkNotUsed(inputVector),
                                      vtkInformationVector* vtkNotUsed(outputVector))
{
  // do nothing let subclasses handle it
  return 1;
}
 
//----------------------------------------------------------------------------
int vtkTestSource::RequestUpdateExtent(
                                          vtkInformation* vtkNotUsed(request),
    vtkInformationVector** inputVector,
    vtkInformationVector* vtkNotUsed(outputVector))
{
  int numInputPorts = this->GetNumberOfInputPorts();
  for (int i=0; i<numInputPorts; i++)
  {
    int numInputConnections = this->GetNumberOfInputConnections(i);
    for (int j=0; j<numInputConnections; j++)
    {
      vtkInformation* inputInfo = inputVector[i]->GetInformationObject(j);
      inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
    }
  }
  return 1;
}
 
//----------------------------------------------------------------------------
// This is the superclasses style of Execute method.  Convert it into
// an imaging style Execute method.
int vtkTestSource::RequestData(
                                  vtkInformation* vtkNotUsed(request),
    vtkInformationVector** vtkNotUsed( inputVector ),
                                       vtkInformationVector* outputVector )
{
  //actually setup the output here
  vtkInformation* outInfoA = outputVector->GetInformationObject(0);
  vtkTestA* outputA = vtkTestA::SafeDownCast(
                                          outInfoA->Get( vtkDataObject::DATA_OBJECT() ) );
 
  outputA->SetValue(111);
 
  vtkInformation* outInfoB = outputVector->GetInformationObject(1);
  vtkTestB* outputB = vtkTestB::SafeDownCast(
                                             outInfoB->Get( vtkDataObject::DATA_OBJECT() ) );
 
  outputB->SetValue(222);
 
  return 1;
}

vtkTestA.h

#ifndef __vtkTestA_h
#define __vtkTestA_h
 
#include "vtkDataObject.h"
 
class vtkTestA : public vtkDataObject
{
  public:
    static vtkTestA* New();
    vtkTypeRevisionMacro(vtkTestA,vtkDataObject);
    void PrintSelf( ostream& os, vtkIndent indent );
 
    vtkGetMacro(Value, double);
    vtkSetMacro(Value, double);
 
  protected:
    vtkTestA();
    ~vtkTestA();
 
  private:
    vtkTestA( const vtkTestA& ); // Not implemented.
    void operator = ( const vtkTestA& ); // Not implemented.
 
    double Value;
};
 
#endif

vtkTestA.cxx

#include "vtkTestA.h"
 
#include "vtkObjectFactory.h"
 
vtkStandardNewMacro(vtkTestA);
vtkCxxRevisionMacro(vtkTestA,"$Revision: 1.46 $");
 
vtkTestA::vtkTestA()
{
  this->Value = 4.5;
}
 
vtkTestA::~vtkTestA()
{
 
}
 
void vtkTestA::PrintSelf( ostream& os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
}

vtkTestB.h

#ifndef __vtkTestB_h
#define __vtkTestB_h
 
#include "vtkDataObject.h"
 
class vtkTestB : public vtkDataObject
{
  public:
    static vtkTestB* New();
    vtkTypeRevisionMacro(vtkTestB,vtkDataObject);
    void PrintSelf( ostream& os, vtkIndent indent );
 
    vtkGetMacro(Value, double);
    vtkSetMacro(Value, double);
 
  protected:
    vtkTestB();
    ~vtkTestB();
 
  private:
    vtkTestB( const vtkTestB& ); // Not implemented.
    void operator = ( const vtkTestB& ); // Not implemented.
 
    double Value;
};
 
#endif

vtkTestB.cxx

#include "vtkTestB.h"
 
#include "vtkObjectFactory.h"
 
vtkStandardNewMacro(vtkTestB);
vtkCxxRevisionMacro(vtkTestB,"$Revision: 1.46 $");
 
vtkTestB::vtkTestB()
{
  this->Value = 4.5;
}
 
vtkTestB::~vtkTestB()
{
 
}
 
void vtkTestB::PrintSelf( ostream& os, vtkIndent indent )
{
  this->Superclass::PrintSelf( os, indent );
}

CMakeLists.txt

cmake_minimum_required(VERSION 2.6)
PROJECT(vtkAlgorithmSourceMultiplePortsExample)
 
FIND_PACKAGE(VTK REQUIRED)
INCLUDE(${VTK_USE_FILE})
 
ADD_EXECUTABLE(vtkAlgorithmSourceMultiplePortsExample vtkAlgorithmSourceMultiplePortsExample.cxx 
vtkTestA.cxx 
vtkTestB.cxx
vtkTestSource.cxx
)
TARGET_LINK_LIBRARIES(vtkAlgorithmSourceMultiplePortsExample vtkHybrid)
Personal tools