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.
245 lines
7.0 KiB
245 lines
7.0 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkSelectVisiblePoints.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 "vtkSelectVisiblePoints.h"
|
|
|
|
#include "vtkCamera.h"
|
|
#include "vtkCellArray.h"
|
|
#include "vtkDataSet.h"
|
|
#include "vtkMatrix4x4.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPoints.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkRenderWindow.h"
|
|
#include "vtkRenderer.h"
|
|
|
|
vtkCxxRevisionMacro(vtkSelectVisiblePoints, "$Revision: 1.36 $");
|
|
vtkStandardNewMacro(vtkSelectVisiblePoints);
|
|
|
|
// Instantiate object with no renderer; window selection turned off;
|
|
// tolerance set to 0.01; and select invisible off.
|
|
vtkSelectVisiblePoints::vtkSelectVisiblePoints()
|
|
{
|
|
this->Renderer = NULL;
|
|
this->SelectionWindow = 0;
|
|
this->Selection[0] = this->Selection[2] = 0;
|
|
this->Selection[1] = this->Selection[3] = 1600;
|
|
this->Tolerance = 0.01;
|
|
this->SelectInvisible = 0;
|
|
}
|
|
|
|
vtkSelectVisiblePoints::~vtkSelectVisiblePoints()
|
|
{
|
|
this->SetRenderer(NULL);
|
|
}
|
|
|
|
int vtkSelectVisiblePoints::RequestData(
|
|
vtkInformation *vtkNotUsed(request),
|
|
vtkInformationVector **inputVector,
|
|
vtkInformationVector *outputVector)
|
|
{
|
|
// get the info objects
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
|
|
vtkInformation *outInfo = outputVector->GetInformationObject(0);
|
|
|
|
// get the input and ouptut
|
|
vtkDataSet *input = vtkDataSet::SafeDownCast(
|
|
inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
vtkPolyData *output = vtkPolyData::SafeDownCast(
|
|
outInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
|
|
vtkIdType ptId, cellId;
|
|
int visible;
|
|
vtkPoints *outPts;
|
|
vtkCellArray *outputVertices;
|
|
vtkPointData *inPD=input->GetPointData();
|
|
vtkPointData *outPD=output->GetPointData();
|
|
vtkIdType numPts=input->GetNumberOfPoints();
|
|
double x[4];
|
|
double dx[3], z;
|
|
int selection[4];
|
|
|
|
if ( this->Renderer == NULL )
|
|
{
|
|
vtkErrorMacro(<<"Renderer must be set");
|
|
return 0;
|
|
}
|
|
|
|
if ( numPts < 1 )
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
outPts = vtkPoints::New();
|
|
outPts->Allocate(numPts/2+1);
|
|
outPD->CopyAllocate(inPD);
|
|
|
|
outputVertices = vtkCellArray::New();
|
|
output->SetVerts(outputVertices);
|
|
outputVertices->Delete();
|
|
|
|
int *size = this->Renderer->GetRenderWindow()->GetSize();
|
|
|
|
// specify a selection window to avoid querying
|
|
if ( this->SelectionWindow )
|
|
{
|
|
for (int i=0; i<4; i++)
|
|
{
|
|
selection[i] = this->Selection[i];
|
|
}
|
|
}
|
|
else
|
|
{
|
|
selection[0] = selection[2] = 0;
|
|
selection[1] = size[0] - 1;
|
|
selection[3] = size[1] - 1;
|
|
}
|
|
|
|
// Grab the composite perspective transform. This matrix is used to convert
|
|
// each point to view coordinates. vtkRenderer provides a WorldToView()
|
|
// method but it computes the composite perspective transform each time
|
|
// WorldToView() is called. This is expensive, so we get the matrix once
|
|
// and handle the transformation ourselves.
|
|
vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
|
|
double view[4];
|
|
matrix->DeepCopy(this->Renderer->GetActiveCamera()->
|
|
GetCompositePerspectiveTransformMatrix(
|
|
this->Renderer->GetTiledAspectRatio(),0,1));
|
|
|
|
// If we have more than a few query points, we grab the z-buffer for the
|
|
// selection region all at once and probe the resulting array. When we
|
|
// have just a few points, we perform individual z-buffer queries.
|
|
const int SimpleQueryLimit = 25;
|
|
float *zPtr = NULL;
|
|
if (numPts > SimpleQueryLimit)
|
|
{
|
|
zPtr = this->Renderer->GetRenderWindow()->
|
|
GetZbufferData(selection[0], selection[2], selection[1], selection[3]);
|
|
}
|
|
|
|
int abort=0;
|
|
vtkIdType progressInterval=numPts/20+1;
|
|
x[3] = 1.0;
|
|
for (cellId=(-1), ptId=0; ptId < numPts && !abort; ptId++)
|
|
{
|
|
// perform conversion
|
|
input->GetPoint(ptId,x);
|
|
matrix->MultiplyPoint(x, view);
|
|
if (view[3] == 0.0)
|
|
{
|
|
continue;
|
|
}
|
|
this->Renderer->SetViewPoint(view[0]/view[3], view[1]/view[3],
|
|
view[2]/view[3]);
|
|
this->Renderer->ViewToDisplay();
|
|
this->Renderer->GetDisplayPoint(dx);
|
|
visible = 0;
|
|
|
|
if ( ! (ptId % progressInterval) )
|
|
{
|
|
this->UpdateProgress((double)ptId/numPts);
|
|
abort = this->GetAbortExecute();
|
|
}
|
|
|
|
// check whether visible and in selection window
|
|
if ( dx[0] >= selection[0] && dx[0] <= selection[1] &&
|
|
dx[1] >= selection[2] && dx[1] <= selection[3] )
|
|
{
|
|
if (numPts > SimpleQueryLimit)
|
|
{
|
|
// Access the value from the captured zbuffer. Note, we only
|
|
// captured a portion of the zbuffer, so we need to offset dx by
|
|
// the selection window.
|
|
z = zPtr[(int)dx[0] - selection[0]
|
|
+ ((int)dx[1] - selection[2])
|
|
*(selection[1] - selection[0] + 1)];
|
|
}
|
|
else
|
|
{
|
|
z = this->Renderer->GetZ(static_cast<int>(dx[0]),
|
|
static_cast<int>(dx[1]));
|
|
}
|
|
if( dx[2] < (z + this->Tolerance) )
|
|
{
|
|
visible = 1;
|
|
}
|
|
}
|
|
|
|
if ( (visible && !this->SelectInvisible) ||
|
|
(!visible && this->SelectInvisible) )
|
|
{
|
|
cellId = outPts->InsertNextPoint(x);
|
|
output->InsertNextCell(VTK_VERTEX, 1, &cellId);
|
|
outPD->CopyData(inPD,ptId,cellId);
|
|
}
|
|
}//for all points
|
|
|
|
output->SetPoints(outPts);
|
|
outPts->Delete();
|
|
output->Squeeze();
|
|
|
|
matrix->Delete();
|
|
|
|
if (zPtr)
|
|
{
|
|
delete [] zPtr;
|
|
}
|
|
|
|
vtkDebugMacro(<<"Selected " << cellId + 1 << " out of "
|
|
<< numPts << " original points");
|
|
|
|
return 1;
|
|
}
|
|
|
|
unsigned long int vtkSelectVisiblePoints::GetMTime()
|
|
{
|
|
unsigned long mTime=this->Superclass::GetMTime();
|
|
unsigned long time;
|
|
|
|
if ( this->Renderer != NULL )
|
|
{
|
|
time = this->Renderer->GetMTime();
|
|
mTime = ( time > mTime ? time : mTime );
|
|
}
|
|
|
|
return mTime;
|
|
}
|
|
|
|
int vtkSelectVisiblePoints::FillInputPortInformation(int, vtkInformation *info)
|
|
{
|
|
info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
|
|
return 1;
|
|
}
|
|
|
|
void vtkSelectVisiblePoints::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "Renderer: " << this->Renderer << "\n";
|
|
os << indent << "Selection Window: "
|
|
<< (this->SelectionWindow ? "On\n" : "Off\n");
|
|
|
|
os << indent << "Selection: \n";
|
|
os << indent << " Xmin,Xmax: (" << this->Selection[0] << ", "
|
|
<< this->Selection[1] << ")\n";
|
|
os << indent << " Ymin,Ymax: (" << this->Selection[2] << ", "
|
|
<< this->Selection[3] << ")\n";
|
|
|
|
os << indent << "Tolerance: " << this->Tolerance << "\n";
|
|
os << indent << "Select Invisible: "
|
|
<< (this->SelectInvisible ? "On\n" : "Off\n");
|
|
}
|
|
|