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.
388 lines
9.5 KiB
388 lines
9.5 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkUGFacetReader.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 "vtkUGFacetReader.h"
|
|
|
|
#include "vtkByteSwap.h"
|
|
#include "vtkCellArray.h"
|
|
#include "vtkFloatArray.h"
|
|
#include "vtkMergePoints.h"
|
|
#include "vtkInformation.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkPolyData.h"
|
|
#include "vtkShortArray.h"
|
|
|
|
vtkCxxRevisionMacro(vtkUGFacetReader, "$Revision: 1.47 $");
|
|
vtkStandardNewMacro(vtkUGFacetReader);
|
|
|
|
// Construct object to extract all parts, and with point merging
|
|
// turned on.
|
|
vtkUGFacetReader::vtkUGFacetReader()
|
|
{
|
|
this->FileName = NULL;
|
|
this->PartColors = NULL;
|
|
this->PartNumber = (-1); //extract all parts
|
|
|
|
this->Merging = 1;
|
|
this->Locator = NULL;
|
|
|
|
this->SetNumberOfInputPorts(0);
|
|
}
|
|
|
|
vtkUGFacetReader::~vtkUGFacetReader()
|
|
{
|
|
if ( this->FileName )
|
|
{
|
|
delete [] this->FileName;
|
|
}
|
|
if ( this->PartColors )
|
|
{
|
|
this->PartColors->Delete();
|
|
}
|
|
if (this->Locator != NULL)
|
|
{
|
|
this->Locator->UnRegister(this);
|
|
this->Locator = NULL;
|
|
}
|
|
}
|
|
|
|
// Overload standard modified time function. If locator is modified,
|
|
// then this object is modified as well.
|
|
unsigned long vtkUGFacetReader::GetMTime()
|
|
{
|
|
unsigned long mTime1=this->Superclass::GetMTime();
|
|
unsigned long mTime2;
|
|
|
|
if (this->Locator)
|
|
{
|
|
mTime2 = this->Locator->GetMTime();
|
|
mTime1 = ( mTime1 > mTime2 ? mTime1 : mTime2 );
|
|
}
|
|
|
|
return mTime1;
|
|
}
|
|
|
|
|
|
int vtkUGFacetReader::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()));
|
|
|
|
FILE *fp;
|
|
char header[36];
|
|
struct {float v1[3], v2[3], v3[3], n1[3], n2[3], n3[3];} facet;
|
|
vtkIdType ptId[3];
|
|
short ugiiColor, direction;
|
|
int numberTris, numFacetSets, setNumber, facetNumber;
|
|
vtkPoints *newPts, *mergedPts;
|
|
vtkFloatArray *newNormals, *mergedNormals;
|
|
vtkCellArray *newPolys, *mergedPolys;
|
|
fpos_t pos;
|
|
int triEstimate;
|
|
|
|
vtkDebugMacro(<<"Reading UG facet file...");
|
|
if ( this->FileName == NULL || strlen(this->FileName) == 0)
|
|
{
|
|
vtkErrorMacro(<<"No FileName specified...please specify one.");
|
|
return 0;
|
|
}
|
|
|
|
// open the file
|
|
if ( (fp = fopen(this->FileName, "rb")) == NULL)
|
|
{
|
|
vtkErrorMacro(<<"Cannot open file specified.");
|
|
return 0;
|
|
}
|
|
|
|
// read the header stuff
|
|
if ( fread (header, 1, 2, fp) <= 0 ||
|
|
fread (&numFacetSets, 4, 1, fp) <= 0 ||
|
|
fread (header, 1, 36, fp) <= 0 )
|
|
{
|
|
vtkErrorMacro(<<"File ended prematurely");
|
|
return 0;
|
|
}
|
|
|
|
// swap bytes since this is a binary file format
|
|
vtkByteSwap::Swap4BE(&numFacetSets);
|
|
|
|
// Estimate how much space we need - find out the size of the
|
|
// file and divide by 72 bytes per triangle
|
|
fgetpos( fp, &pos );
|
|
fseek( fp, 0L, SEEK_END );
|
|
triEstimate = ftell( fp ) / 72;
|
|
fsetpos( fp, &pos );
|
|
|
|
// allocate memory
|
|
if ( ! this->PartColors )
|
|
{
|
|
this->PartColors = vtkShortArray::New();
|
|
this->PartColors->Allocate(100);
|
|
}
|
|
else
|
|
{
|
|
this->PartColors->Reset();
|
|
}
|
|
|
|
newPts = vtkPoints::New();
|
|
newPts->Allocate(triEstimate,triEstimate);
|
|
newNormals = vtkFloatArray::New();
|
|
newNormals->SetNumberOfComponents(3);
|
|
newNormals->Allocate(3*triEstimate,3*triEstimate);
|
|
newPolys = vtkCellArray::New();
|
|
newPolys->Allocate(newPolys->EstimateSize(triEstimate,3),triEstimate);
|
|
|
|
// loop over all facet sets, extracting triangles
|
|
for (setNumber=0; setNumber < numFacetSets; setNumber++)
|
|
{
|
|
|
|
if ( fread (&ugiiColor, 2, 1, fp) <= 0 ||
|
|
fread (&direction, 2, 1, fp) <= 0 ||
|
|
fread (&numberTris, 4, 1, fp) <= 0 )
|
|
{
|
|
vtkErrorMacro(<<"File ended prematurely");
|
|
break;
|
|
}
|
|
|
|
// swap bytes if necc
|
|
vtkByteSwap::Swap4BE(&numberTris);
|
|
vtkByteSwap::Swap2BERange(&ugiiColor,1);
|
|
vtkByteSwap::Swap2BERange(&direction,1);
|
|
|
|
this->PartColors->InsertNextValue(ugiiColor);
|
|
|
|
for (facetNumber=0; facetNumber < numberTris; facetNumber++)
|
|
{
|
|
if ( fread(&facet,72,1,fp) <= 0 )
|
|
{
|
|
vtkErrorMacro(<<"File ended prematurely");
|
|
break;
|
|
}
|
|
|
|
// swap bytes if necc
|
|
vtkByteSwap::Swap4BERange((float *)(&facet),18);
|
|
|
|
if ( this->PartNumber == -1 || this->PartNumber == setNumber )
|
|
{
|
|
ptId[0] = newPts->InsertNextPoint(facet.v1);
|
|
ptId[1] = newPts->InsertNextPoint(facet.v2);
|
|
ptId[2] = newPts->InsertNextPoint(facet.v3);
|
|
|
|
newNormals->InsertTuple(ptId[0],facet.n1);
|
|
newNormals->InsertTuple(ptId[1],facet.n2);
|
|
newNormals->InsertTuple(ptId[2],facet.n3);
|
|
|
|
newPolys->InsertNextCell(3,ptId);
|
|
}//if appropriate part
|
|
}//for all facets in this set
|
|
}//for this facet set
|
|
|
|
// update output
|
|
vtkDebugMacro(<<"Read "
|
|
<< newPts->GetNumberOfPoints() << " points, "
|
|
<< newPolys->GetNumberOfCells() << " triangles.");
|
|
|
|
fclose(fp);
|
|
|
|
//
|
|
// Merge points/triangles if requested
|
|
//
|
|
if ( this->Merging )
|
|
{
|
|
int i;
|
|
vtkIdType *pts = 0;
|
|
vtkIdType nodes[3];
|
|
vtkIdType npts;
|
|
double *x;
|
|
|
|
mergedPts = vtkPoints::New();
|
|
mergedPts->Allocate(newPts->GetNumberOfPoints()/3);
|
|
mergedNormals = vtkFloatArray::New();
|
|
mergedNormals->SetNumberOfComponents(3);
|
|
mergedNormals->Allocate(newNormals->GetNumberOfTuples());
|
|
mergedPolys = vtkCellArray::New();
|
|
mergedPolys->Allocate(newPolys->GetSize());
|
|
|
|
if ( this->Locator == NULL )
|
|
{
|
|
this->CreateDefaultLocator();
|
|
}
|
|
this->Locator->InitPointInsertion (mergedPts, newPts->GetBounds());
|
|
|
|
for (newPolys->InitTraversal(); newPolys->GetNextCell(npts,pts); )
|
|
{
|
|
for (i=0; i < 3; i++)
|
|
{
|
|
x = newPts->GetPoint(pts[i]);
|
|
if ( this->Locator->InsertUniquePoint(x, nodes[i]) )
|
|
{
|
|
mergedNormals->InsertTuple(nodes[i],newNormals->GetTuple(pts[i]));
|
|
}
|
|
}
|
|
|
|
if ( nodes[0] != nodes[1] && nodes[0] != nodes[2] &&
|
|
nodes[1] != nodes[2] )
|
|
{
|
|
mergedPolys->InsertNextCell(3,nodes);
|
|
}
|
|
}
|
|
|
|
newPts->Delete();
|
|
newNormals->Delete();
|
|
newPolys->Delete();
|
|
|
|
vtkDebugMacro(<< "Merged to: "
|
|
<< mergedPts->GetNumberOfPoints() << " points, "
|
|
<< mergedPolys->GetNumberOfCells() << " triangles");
|
|
}
|
|
else
|
|
{
|
|
mergedPts = newPts;
|
|
mergedNormals = newNormals;
|
|
mergedPolys = newPolys;
|
|
}
|
|
//
|
|
// Update ourselves
|
|
//
|
|
output->SetPoints(mergedPts);
|
|
mergedPts->Delete();
|
|
|
|
output->GetPointData()->SetNormals(mergedNormals);
|
|
mergedNormals->Delete();
|
|
|
|
output->SetPolys(mergedPolys);
|
|
mergedPolys->Delete();
|
|
|
|
if (this->Locator)
|
|
{
|
|
this->Locator->Initialize(); //free storage
|
|
}
|
|
|
|
output->Squeeze();
|
|
|
|
return 1;
|
|
}
|
|
|
|
int vtkUGFacetReader::GetNumberOfParts()
|
|
{
|
|
char header[36];
|
|
FILE *fp;
|
|
int numberOfParts;
|
|
|
|
if ( this->FileName == NULL || strlen(this->FileName) == 0)
|
|
{
|
|
vtkErrorMacro(<<"No FileName specified...please specify one.");
|
|
return 0;
|
|
}
|
|
|
|
// open the file
|
|
if ( (fp = fopen(this->FileName, "rb")) == NULL)
|
|
{
|
|
vtkErrorMacro(<<"Cannot open file specified.");
|
|
return 0;
|
|
}
|
|
|
|
// read the header stuff
|
|
if ( fread (header, 1, 2, fp) <= 0 ||
|
|
fread (&numberOfParts, 4, 1, fp) <= 0 ||
|
|
fread (header, 1, 36, fp) <= 0 )
|
|
{
|
|
vtkErrorMacro(<<"File ended prematurely");
|
|
fclose(fp);
|
|
return 0;
|
|
}
|
|
|
|
// swap bytes if necc
|
|
vtkByteSwap::Swap4BE(&numberOfParts);
|
|
|
|
fclose(fp);
|
|
return numberOfParts;
|
|
}
|
|
|
|
// Retrieve color index for the parts in the file.
|
|
short vtkUGFacetReader::GetPartColorIndex(int partId)
|
|
{
|
|
if ( this->PartColors == NULL )
|
|
{
|
|
this->Update();
|
|
}
|
|
|
|
if ( !this->PartColors ||
|
|
partId < 0 || partId > this->PartColors->GetMaxId() )
|
|
{
|
|
return 0;
|
|
}
|
|
else
|
|
{
|
|
return this->PartColors->GetValue(partId);
|
|
}
|
|
}
|
|
|
|
// Specify a spatial locator for merging points. By
|
|
// default an instance of vtkMergePoints is used.
|
|
void vtkUGFacetReader::SetLocator(vtkPointLocator *locator)
|
|
{
|
|
if ( this->Locator == locator )
|
|
{
|
|
return;
|
|
}
|
|
if (this->Locator != NULL)
|
|
{
|
|
this->Locator->UnRegister(this);
|
|
this->Locator = NULL;
|
|
}
|
|
if (locator != NULL)
|
|
{
|
|
locator->Register(this);
|
|
}
|
|
this->Locator = locator;
|
|
this->Modified();
|
|
}
|
|
|
|
void vtkUGFacetReader::CreateDefaultLocator()
|
|
{
|
|
if ( this->Locator == NULL )
|
|
{
|
|
this->Locator = vtkMergePoints::New();
|
|
}
|
|
}
|
|
|
|
void vtkUGFacetReader::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "File Name: "
|
|
<< (this->FileName ? this->FileName : "(none)") << "\n";
|
|
|
|
os << indent << "Part Number: " << this->PartNumber << "\n";
|
|
|
|
os << indent << "Merging: " << (this->Merging ? "On\n" : "Off\n");
|
|
if ( this->Locator )
|
|
{
|
|
os << indent << "Locator: " << this->Locator << "\n";
|
|
}
|
|
else
|
|
{
|
|
os << indent << "Locator: (none)\n";
|
|
}
|
|
}
|
|
|