Cloned library of VTK-5.0.0 with extra build files for internal package management.
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.
 
 
 
 
 
 

302 lines
9.5 KiB

/*=========================================================================
Program: Visualization Toolkit
Module: $RCSfile: vtkPLYReader.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 "vtkPLYReader.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkPointData.h"
#include "vtkFloatArray.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkObjectFactory.h"
#include "vtkPLY.h"
#include "vtkPolyData.h"
#include <ctype.h>
#include <stddef.h>
vtkCxxRevisionMacro(vtkPLYReader, "$Revision: 1.19 $");
vtkStandardNewMacro(vtkPLYReader);
#ifndef true
#define true 1
#endif
#ifndef false
#define false 0
#endif
// Construct object with merging set to true.
vtkPLYReader::vtkPLYReader()
{
this->FileName = NULL;
this->SetNumberOfInputPorts(0);
}
vtkPLYReader::~vtkPLYReader()
{
if (this->FileName)
{
delete [] this->FileName;
}
}
typedef struct _plyVertex {
float x[3]; // the usual 3-space position of a vertex
unsigned char red;
unsigned char green;
unsigned char blue;
} plyVertex;
typedef struct _plyFace {
unsigned char intensity; // optional face attributes
unsigned char red;
unsigned char green;
unsigned char blue;
unsigned char nverts; // number of vertex indices in list
int *verts; // vertex index list
} plyFace;
int vtkPLYReader::RequestData(
vtkInformation *vtkNotUsed(request),
vtkInformationVector **vtkNotUsed(inputVector),
vtkInformationVector *outputVector)
{
// get the info object
vtkInformation *outInfo = outputVector->GetInformationObject(0);
// get the ouptut
vtkPolyData *output = vtkPolyData::SafeDownCast(
outInfo->Get(vtkDataObject::DATA_OBJECT()));
PlyProperty vertProps[] = {
{"x", PLY_FLOAT, PLY_FLOAT, static_cast<int>(offsetof(plyVertex,x)),
0, 0, 0, 0},
{"y", PLY_FLOAT, PLY_FLOAT, static_cast<int>(offsetof(plyVertex,x)+sizeof(float)),
0, 0, 0, 0},
{"z", PLY_FLOAT, PLY_FLOAT, static_cast<int>(offsetof(plyVertex,x)+sizeof(float)+sizeof(float)),
0, 0, 0, 0},
{"red", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyVertex,red)), 0, 0, 0, 0},
{"green", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyVertex,green)), 0, 0, 0, 0},
{"blue", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyVertex,blue)), 0, 0, 0, 0},
};
PlyProperty faceProps[] = {
{"vertex_indices", PLY_INT, PLY_INT,
static_cast<int>(offsetof(plyFace,verts)),
1, PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyFace,nverts))},
{"intensity", PLY_UCHAR, PLY_UCHAR,
static_cast<int>(offsetof(plyFace,intensity)), 0, 0, 0, 0},
{"red", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyFace,red)), 0, 0, 0, 0},
{"green", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyFace,green)), 0, 0, 0, 0},
{"blue", PLY_UCHAR, PLY_UCHAR, static_cast<int>(offsetof(plyFace,blue)), 0, 0, 0, 0},
};
int i, j, k;
int numPts=0, numPolys=0;
if (!this->FileName)
{
vtkErrorMacro(<<"A File Name must be specified.");
return 0;
}
// open a PLY file for reading
PlyFile *ply;
int nelems, fileType, numElems, nprops;
char **elist, *elemName;
float version;
if ( !(ply = vtkPLY::ply_open_for_reading(this->FileName, &nelems, &elist,
&fileType, &version)) )
{
vtkErrorMacro(<<"Could not open PLY file");
return 0;
}
// Check to make sure that we can read geometry
PlyElement *elem;
int index;
if ( (elem = vtkPLY::find_element (ply, "vertex")) == NULL ||
vtkPLY::find_property (elem, "x", &index) == NULL ||
vtkPLY::find_property (elem, "y", &index) == NULL ||
vtkPLY::find_property (elem, "z", &index) == NULL ||
(elem = vtkPLY::find_element (ply, "face")) == NULL ||
vtkPLY::find_property (elem, "vertex_indices", &index) == NULL )
{
vtkErrorMacro(<<"Cannot read geometry");
vtkPLY::ply_close (ply);
}
// Check for optional attribute data. We can handle intensity; and the
// triplet red, green, blue.
unsigned char intensityAvailable=false, RGBCellsAvailable=false, RGBPointsAvailable=false;
vtkUnsignedCharArray *intensity=NULL;
vtkUnsignedCharArray *RGBCells=NULL;
vtkUnsignedCharArray *RGBPoints=NULL;
if ( (elem = vtkPLY::find_element (ply, "face")) != NULL &&
vtkPLY::find_property (elem, "intensity", &index) != NULL )
{
intensity = vtkUnsignedCharArray::New();
intensity->SetName("intensity");
intensityAvailable = true;
output->GetCellData()->AddArray(intensity);
output->GetCellData()->SetActiveScalars("intensity");
intensity->Delete();
}
if ( (elem = vtkPLY::find_element (ply, "face")) != NULL &&
vtkPLY::find_property (elem, "red", &index) != NULL &&
vtkPLY::find_property (elem, "green", &index) != NULL &&
vtkPLY::find_property (elem, "blue", &index) != NULL )
{
RGBCells = vtkUnsignedCharArray::New();
RGBCells->SetName("RGB");
RGBCellsAvailable = true;
output->GetCellData()->AddArray(RGBCells);
output->GetCellData()->SetActiveScalars("RGB");
RGBCells->Delete();
}
if ( (elem = vtkPLY::find_element (ply, "vertex")) != NULL &&
vtkPLY::find_property (elem, "red", &index) != NULL &&
vtkPLY::find_property (elem, "green", &index) != NULL &&
vtkPLY::find_property (elem, "blue", &index) != NULL )
{
RGBPoints = vtkUnsignedCharArray::New();
RGBPointsAvailable = true;
RGBPoints->SetName("RGB");
output->GetPointData()->SetScalars(RGBPoints);
RGBPoints->Delete();
}
// Okay, now we can grab the data
for (i = 0; i < nelems; i++)
{
//get the description of the first element */
elemName = elist[i];
vtkPLY::ply_get_element_description (ply, elemName, &numElems, &nprops);
// if we're on vertex elements, read them in
if ( elemName && !strcmp ("vertex", elemName) )
{
// Create a list of points
numPts = numElems;
vtkPoints *pts = vtkPoints::New();
pts->SetDataTypeToFloat();
pts->SetNumberOfPoints(numPts);
// Setup to read the PLY elements
vtkPLY::ply_get_property (ply, elemName, &vertProps[0]);
vtkPLY::ply_get_property (ply, elemName, &vertProps[1]);
vtkPLY::ply_get_property (ply, elemName, &vertProps[2]);
if ( RGBPointsAvailable )
{
vtkPLY::ply_get_property (ply, elemName, &vertProps[3]);
vtkPLY::ply_get_property (ply, elemName, &vertProps[4]);
vtkPLY::ply_get_property (ply, elemName, &vertProps[5]);
RGBPoints->SetNumberOfComponents(3);
RGBPoints->SetNumberOfTuples(numPts);
}
plyVertex vertex;
for (j=0; j < numPts; j++)
{
vtkPLY::ply_get_element (ply, (void *) &vertex);
pts->SetPoint (j, vertex.x);
if ( RGBPointsAvailable )
{
RGBPoints->SetTuple3(j,vertex.red,vertex.green,vertex.blue);
}
}
output->SetPoints(pts);
pts->Delete();
}//if vertex
else if ( elemName && !strcmp ("face", elemName) )
{
// Create a polygonal array
numPolys = numElems;
vtkCellArray *polys = vtkCellArray::New();
polys->Allocate(polys->EstimateSize(numPolys,3),numPolys/2);
plyFace face;
int verts[256];
vtkIdType vtkVerts[256];
// Get the face properties
vtkPLY::ply_get_property (ply, elemName, &faceProps[0]);
if ( intensityAvailable )
{
vtkPLY::ply_get_property (ply, elemName, &faceProps[1]);
RGBCells->SetNumberOfComponents(1);
RGBCells->SetNumberOfTuples(numPolys);
}
if ( RGBCellsAvailable )
{
vtkPLY::ply_get_property (ply, elemName, &faceProps[2]);
vtkPLY::ply_get_property (ply, elemName, &faceProps[3]);
vtkPLY::ply_get_property (ply, elemName, &faceProps[4]);
RGBCells->SetNumberOfComponents(3);
RGBCells->SetNumberOfTuples(numPolys);
}
// grab all the face elements
for (j=0; j < numPolys; j++)
{
//grab and element from the file
face.verts = verts;
vtkPLY::ply_get_element (ply, (void *) &face);
for (k=0; k<face.nverts; k++)
{
vtkVerts[k] = face.verts[k];
}
polys->InsertNextCell(face.nverts,vtkVerts);
if ( intensityAvailable )
{
intensity->SetValue(j,face.intensity);
}
if ( RGBCellsAvailable )
{
RGBCells->SetValue(3*j,face.red);
RGBCells->SetValue(3*j+1,face.green);
RGBCells->SetValue(3*j+2,face.blue);
}
}
output->SetPolys(polys);
polys->Delete();
}//if face
free(elist[i]); //allocated by ply_open_for_reading
}//for all elements of the PLY file
free(elist); //allocated by ply_open_for_reading
vtkDebugMacro( <<"Read: " << numPts << " points, "
<< numPolys << " polygons");
// close the PLY file
vtkPLY::ply_close (ply);
return 1;
}
void vtkPLYReader::PrintSelf(ostream& os, vtkIndent indent)
{
this->Superclass::PrintSelf(os,indent);
os << indent << "File Name: "
<< (this->FileName ? this->FileName : "(none)") << "\n";
}