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.
353 lines
10 KiB
353 lines
10 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkProgrammableGlyphFilter.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 "vtkProgrammableGlyphFilter.h"
|
|
|
|
#include "vtkCell.h"
|
|
#include "vtkCellData.h"
|
|
#include "vtkDataSet.h"
|
|
#include "vtkExecutive.h"
|
|
#include "vtkFloatArray.h"
|
|
#include "vtkIdList.h"
|
|
#include "vtkMath.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkTransform.h"
|
|
|
|
vtkCxxRevisionMacro(vtkProgrammableGlyphFilter, "$Revision: 1.32.12.1 $");
|
|
vtkStandardNewMacro(vtkProgrammableGlyphFilter);
|
|
|
|
// Construct object with scaling on, scaling mode is by scalar value,
|
|
// scale factor = 1.0, the range is (0,1), orient geometry is on, and
|
|
// orientation is by vector. Clamping and indexing are turned off. No
|
|
// initial sources are defined.
|
|
vtkProgrammableGlyphFilter::vtkProgrammableGlyphFilter()
|
|
{
|
|
this->GlyphMethod = NULL;
|
|
this->GlyphMethodArgDelete = NULL;
|
|
this->GlyphMethodArg = NULL;
|
|
|
|
this->Point[0] = this->Point[1] = this->Point[2] = 0.0;
|
|
this->PointId = -1;
|
|
this->PointData = NULL;
|
|
|
|
this->ColorMode = VTK_COLOR_BY_INPUT;
|
|
|
|
this->SetNumberOfInputPorts(2);
|
|
}
|
|
|
|
vtkProgrammableGlyphFilter::~vtkProgrammableGlyphFilter()
|
|
{
|
|
if ((this->GlyphMethodArg)&&(this->GlyphMethodArgDelete))
|
|
{
|
|
(*this->GlyphMethodArgDelete)(this->GlyphMethodArg);
|
|
}
|
|
}
|
|
|
|
// Specify a source object at a specified table location.
|
|
void vtkProgrammableGlyphFilter::SetSource(vtkPolyData *pd)
|
|
{
|
|
this->SetInput(1, pd);
|
|
}
|
|
|
|
// Get a pointer to a source object at a specified table location.
|
|
vtkPolyData *vtkProgrammableGlyphFilter::GetSource()
|
|
{
|
|
if (this->GetNumberOfInputConnections(1) < 1)
|
|
{
|
|
return NULL;
|
|
}
|
|
|
|
return vtkPolyData::SafeDownCast(
|
|
this->GetExecutive()->GetInputData(1, 0));
|
|
}
|
|
|
|
int vtkProgrammableGlyphFilter::RequestData(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
// get the input and ouptut
|
|
vtkDataSet *input = vtkDataSet::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkPolyData *source = vtkPolyData::SafeDownCast(
|
|
sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkPointData *inputPD = input->GetPointData();
|
|
vtkCellData *inputCD = input->GetCellData();
|
|
vtkPointData *outputPD = output->GetPointData();
|
|
vtkCellData *outputCD = output->GetCellData();
|
|
vtkPoints *newPts, *sourcePts;
|
|
vtkFloatArray *ptScalars=NULL, *cellScalars=NULL;
|
|
vtkDataArray *inPtScalars = NULL, *inCellScalars = NULL;
|
|
vtkIdType numPts = input->GetNumberOfPoints();
|
|
vtkPointData *sourcePD;
|
|
vtkCellData *sourceCD;
|
|
vtkIdType numSourcePts, numSourceCells, ptOffset=0, cellId, ptId, id, idx;
|
|
int i, npts;
|
|
vtkIdList *pts;
|
|
vtkIdList *cellPts;
|
|
vtkCell *cell;
|
|
|
|
// Initialize
|
|
vtkDebugMacro(<<"Generating programmable glyphs!");
|
|
|
|
if ( numPts < 1 )
|
|
{
|
|
vtkErrorMacro(<<"No input points to glyph");
|
|
}
|
|
|
|
pts=vtkIdList::New();
|
|
pts->Allocate(VTK_CELL_SIZE);
|
|
sourcePD = source->GetPointData();
|
|
sourceCD = source->GetCellData();
|
|
numSourcePts = source->GetNumberOfPoints();
|
|
numSourceCells = source->GetNumberOfCells();
|
|
|
|
outputPD->CopyScalarsOff(); //'cause we control the coloring process
|
|
outputCD->CopyScalarsOff();
|
|
|
|
output->Allocate(numSourceCells*numPts,numSourceCells*numPts);
|
|
outputPD->CopyAllocate(sourcePD, numSourcePts*numPts, numSourcePts*numPts);
|
|
outputCD->CopyAllocate(sourceCD, numSourceCells*numPts, numSourceCells*numPts);
|
|
newPts = vtkPoints::New();
|
|
newPts->Allocate(numSourcePts*numPts);
|
|
|
|
// figure out how to color the data and setup
|
|
if ( this->ColorMode == VTK_COLOR_BY_INPUT )
|
|
{
|
|
if ( (inPtScalars = inputPD->GetScalars()) )
|
|
{
|
|
ptScalars = vtkFloatArray::New();
|
|
ptScalars->Allocate(numSourcePts*numPts);
|
|
}
|
|
if ( (inCellScalars = inputCD->GetScalars()) )
|
|
{
|
|
cellScalars = vtkFloatArray::New();
|
|
cellScalars->Allocate(numSourcePts*numPts);
|
|
}
|
|
}
|
|
|
|
else
|
|
{
|
|
if ( sourcePD->GetScalars() )
|
|
{
|
|
ptScalars = vtkFloatArray::New();
|
|
ptScalars->Allocate(numSourcePts*numPts);
|
|
}
|
|
if ( sourceCD->GetScalars() )
|
|
{
|
|
cellScalars = vtkFloatArray::New();
|
|
cellScalars->Allocate(numSourcePts*numPts);
|
|
}
|
|
}
|
|
|
|
// Loop over all points, invoking glyph method and Update(),
|
|
// then append output of source to output of this filter.
|
|
//
|
|
// this->Updating = 1; // to prevent infinite recursion
|
|
this->PointData = input->GetPointData();
|
|
for (this->PointId=0; this->PointId < numPts; this->PointId++)
|
|
{
|
|
if ( ! (this->PointId % 10000) )
|
|
{
|
|
this->UpdateProgress ((double)this->PointId/numPts);
|
|
if (this->GetAbortExecute())
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
|
|
input->GetPoint(this->PointId, this->Point);
|
|
|
|
if ( this->GlyphMethod )
|
|
{
|
|
(*this->GlyphMethod)(this->GlyphMethodArg);
|
|
}
|
|
|
|
if ( source )
|
|
{
|
|
source->Update();
|
|
|
|
sourcePts = source->GetPoints();
|
|
numSourcePts = source->GetNumberOfPoints();
|
|
numSourceCells = source->GetNumberOfCells();
|
|
sourcePD = source->GetPointData();
|
|
sourceCD = source->GetCellData();
|
|
|
|
if ( this->ColorMode == VTK_COLOR_BY_SOURCE )
|
|
{
|
|
inPtScalars = sourcePD->GetScalars();
|
|
inCellScalars = sourceCD->GetScalars();
|
|
}
|
|
|
|
// Copy all data from source to output.
|
|
for (ptId=0; ptId < numSourcePts; ptId++)
|
|
{
|
|
id = newPts->InsertNextPoint(sourcePts->GetPoint(ptId));
|
|
outputPD->CopyData(sourcePD, ptId, id);
|
|
}
|
|
|
|
for (cellId=0; cellId < numSourceCells; cellId++)
|
|
{
|
|
cell = source->GetCell(cellId);
|
|
cellPts = cell->GetPointIds();
|
|
npts = cellPts->GetNumberOfIds();
|
|
for (pts->Reset(), i=0; i < npts; i++)
|
|
{
|
|
pts->InsertId(i,cellPts->GetId(i) + ptOffset);
|
|
}
|
|
id = output->InsertNextCell(cell->GetCellType(),pts);
|
|
outputCD->CopyData(sourceCD, cellId, id);
|
|
}
|
|
|
|
// If we're coloring the output with scalars, do that now
|
|
if ( ptScalars )
|
|
{
|
|
for (ptId=0; ptId < numSourcePts; ptId++)
|
|
{
|
|
idx = (this->ColorMode == VTK_COLOR_BY_INPUT ? this->PointId : ptId);
|
|
ptScalars->InsertNextValue(inPtScalars->GetComponent(idx,0));
|
|
}
|
|
}
|
|
else if ( cellScalars )
|
|
{
|
|
for (cellId=0; cellId < numSourceCells; cellId++)
|
|
{
|
|
idx = (this->ColorMode == VTK_COLOR_BY_INPUT ? this->PointId : cellId);
|
|
cellScalars->InsertNextValue(inCellScalars->GetComponent(idx,0));
|
|
}
|
|
}
|
|
|
|
ptOffset += numSourcePts;
|
|
|
|
}//if a source is available
|
|
} //for all input points
|
|
|
|
// this->Updating = 0;
|
|
|
|
pts->Delete();
|
|
|
|
output->SetPoints(newPts);
|
|
newPts->Delete();
|
|
|
|
if ( ptScalars )
|
|
{
|
|
idx = outputPD->AddArray(ptScalars);
|
|
outputPD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
|
|
ptScalars->Delete();
|
|
}
|
|
|
|
if ( cellScalars )
|
|
{
|
|
idx = outputCD->AddArray(cellScalars);
|
|
outputCD->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
|
|
cellScalars->Delete();
|
|
}
|
|
|
|
output->Squeeze();
|
|
|
|
return 1;
|
|
}
|
|
|
|
|
|
// Specify function to be called before object executes.
|
|
void vtkProgrammableGlyphFilter::SetGlyphMethod(void (*f)(void *), void *arg)
|
|
{
|
|
if ( f != this->GlyphMethod || arg != this->GlyphMethodArg )
|
|
{
|
|
// delete the current arg if there is one and a delete meth
|
|
if ((this->GlyphMethodArg)&&(this->GlyphMethodArgDelete))
|
|
{
|
|
(*this->GlyphMethodArgDelete)(this->GlyphMethodArg);
|
|
}
|
|
this->GlyphMethod = f;
|
|
this->GlyphMethodArg = arg;
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// Set the arg delete method. This is used to free user memory.
|
|
void vtkProgrammableGlyphFilter::SetGlyphMethodArgDelete(void (*f)(void *))
|
|
{
|
|
if ( f != this->GlyphMethodArgDelete)
|
|
{
|
|
this->GlyphMethodArgDelete = f;
|
|
this->Modified();
|
|
}
|
|
}
|
|
|
|
// Description:
|
|
// Return the method of coloring as a descriptive character string.
|
|
const char *vtkProgrammableGlyphFilter::GetColorModeAsString(void)
|
|
{
|
|
if ( this->ColorMode == VTK_COLOR_BY_INPUT )
|
|
{
|
|
return "ColorByInput";
|
|
}
|
|
else
|
|
{
|
|
return "ColorBySource";
|
|
}
|
|
}
|
|
|
|
int vtkProgrammableGlyphFilter::FillInputPortInformation(int port,
|
|
vtkInformation *info)
|
|
{
|
|
if (port == 0)
|
|
{
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
|
return 1;
|
|
}
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPolyData");
|
|
return 1;
|
|
}
|
|
|
|
void vtkProgrammableGlyphFilter::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Color Mode: " << this->GetColorModeAsString() << endl;
|
|
os << indent << "Point Id: " << this->PointId << "\n";
|
|
os << indent << "Point: " << this->Point[0]
|
|
<< ", " << this->Point[1]
|
|
<< ", " << this->Point[2] << "\n";
|
|
if (this->PointData)
|
|
{
|
|
os << indent << "PointData: " << this->PointData << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "PointData: (not defined)\n";
|
|
}
|
|
|
|
if ( this->GlyphMethod )
|
|
{
|
|
os << indent << "Glyph Method defined\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "No Glyph Method\n";
|
|
}
|
|
}
|
|
|