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.
 
 
 
 
 
 

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";
}
}