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.
323 lines
8.5 KiB
323 lines
8.5 KiB
/*=========================================================================
|
|
|
|
Program: Visualization Toolkit
|
|
Module: $RCSfile: vtkFacetWriter.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 "vtkFacetWriter.h"
|
|
|
|
#include "vtkUnstructuredGrid.h"
|
|
#include "vtkObjectFactory.h"
|
|
#include "vtkErrorCode.h"
|
|
#include "vtkCellType.h"
|
|
#include "vtkCellArray.h"
|
|
#include "vtkGarbageCollector.h"
|
|
#include "vtkAppendFilter.h"
|
|
#include "vtkPointData.h"
|
|
#include "vtkCellData.h"
|
|
#include "vtkInformationVector.h"
|
|
#include "vtkInformation.h"
|
|
|
|
#include "vtkUnsignedIntArray.h"
|
|
#include "vtkDoubleArray.h"
|
|
#include "vtkSmartPointer.h"
|
|
|
|
#include <sys/stat.h>
|
|
#include <vtkstd/string>
|
|
#include <vtkstd/vector>
|
|
|
|
vtkCxxRevisionMacro(vtkFacetWriter, "$Revision: 1.5 $");
|
|
vtkStandardNewMacro(vtkFacetWriter);
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkFacetWriter::vtkFacetWriter()
|
|
{
|
|
this->FileName = NULL;
|
|
this->OutputStream = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
vtkFacetWriter::~vtkFacetWriter()
|
|
{
|
|
this->SetFileName(0);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFacetWriter::Write()
|
|
{
|
|
this->WriteToStream(0);
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkFacetWriter::RequestData(
|
|
vtkInformation* vtkNotUsed( request ),
|
|
vtkInformationVector** inputVector,
|
|
vtkInformationVector* vtkNotUsed( outputVector) )
|
|
{
|
|
this->SetErrorCode(vtkErrorCode::NoError);
|
|
|
|
int cleanStream = 0;
|
|
if ( !this->OutputStream )
|
|
{
|
|
if ( !this->FileName )
|
|
{
|
|
vtkErrorMacro("File name not specified");
|
|
return 0;
|
|
}
|
|
|
|
this->OutputStream = new ofstream(this->FileName);
|
|
if ( !this->OutputStream )
|
|
{
|
|
vtkErrorMacro("Error opening file: " << this->FileName << " for writing");
|
|
return 0;
|
|
}
|
|
cleanStream = 1;
|
|
}
|
|
|
|
if ( !this->OutputStream )
|
|
{
|
|
vtkErrorMacro("No output stream");
|
|
return 0;
|
|
}
|
|
|
|
int cc;
|
|
int len = inputVector[0]->GetNumberOfInformationObjects();
|
|
*this->OutputStream << "FACET FILE FROM VTK" << endl
|
|
<< len << endl;
|
|
|
|
for ( cc =0; cc < len; cc ++ )
|
|
{
|
|
vtkInformation *inInfo = inputVector[0]->GetInformationObject(cc);
|
|
vtkPolyData *input =
|
|
vtkPolyData::SafeDownCast(inInfo->Get(vtkDataObject::DATA_OBJECT()));
|
|
if ( !this->WriteDataToStream(this->OutputStream, input) )
|
|
{
|
|
if ( cleanStream )
|
|
{
|
|
delete this->OutputStream;
|
|
this->OutputStream = 0;
|
|
}
|
|
return 0;
|
|
}
|
|
}
|
|
if ( cleanStream )
|
|
{
|
|
delete this->OutputStream;
|
|
this->OutputStream = 0;
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
void vtkFacetWriter::WriteToStream(ostream* ost)
|
|
{
|
|
this->OutputStream = ost;
|
|
// we always write, even if nothing has changed, so send a modified
|
|
this->Modified();
|
|
this->UpdateInformation();
|
|
this->GetInput()->SetUpdateExtent(this->GetInput()->GetWholeExtent());
|
|
this->Update();
|
|
this->OutputStream = 0;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkFacetWriter::WriteDataToStream(ostream* ost, vtkPolyData* data)
|
|
{
|
|
*ost << "Element" << data << endl
|
|
<< "0" << endl
|
|
<< data->GetNumberOfPoints() << " 0 0" << endl;
|
|
vtkIdType point;
|
|
for ( point = 0; point < data->GetNumberOfPoints(); point ++ )
|
|
{
|
|
double xyz[3];
|
|
data->GetPoint(point, xyz);
|
|
*ost << xyz[0] << " " << xyz[1] << " " << xyz[2] << endl;
|
|
}
|
|
*ost << "1" << endl
|
|
<< "Element" << data << endl;
|
|
int written = 0;
|
|
vtkCellArray* ca;
|
|
vtkIdType numCells;
|
|
vtkIdType totalCells = 0;
|
|
int material = 0;
|
|
int part = 0;
|
|
vtkIdType cc;
|
|
|
|
if ( data->GetVerts()->GetNumberOfCells() )
|
|
{
|
|
// This test is needed if another cell type is written above this
|
|
// block. We must remove it here because it produces an
|
|
// unreachable code warning.
|
|
//
|
|
//if ( written )
|
|
// {
|
|
// vtkErrorMacro("Multiple different cells in the poly data");
|
|
// return 0;
|
|
// }
|
|
ca = data->GetVerts();
|
|
numCells = ca->GetNumberOfCells();
|
|
vtkIdType numPts = 0;
|
|
vtkIdType *pts = NULL;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
// Each vertex is one cell
|
|
for ( cc = 0; cc < numPts; cc ++ )
|
|
{
|
|
totalCells ++;
|
|
}
|
|
}
|
|
*ost << totalCells << " 1" << endl;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
for ( cc = 0; cc < numPts; cc ++ )
|
|
{
|
|
// Indices of point starts with 1
|
|
vtkIdType pointIndex = pts[cc] + 1;
|
|
*ost << pointIndex << " " << material << " " << part << endl;
|
|
}
|
|
}
|
|
written = 1;
|
|
}
|
|
|
|
if ( data->GetLines()->GetNumberOfCells() )
|
|
{
|
|
if ( written )
|
|
{
|
|
vtkErrorMacro("Multiple different cells in the poly data");
|
|
return 0;
|
|
}
|
|
ca = data->GetLines();
|
|
numCells = ca->GetNumberOfCells();
|
|
vtkIdType numPts = 0;
|
|
vtkIdType *pts = NULL;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
// One line per cell
|
|
for ( cc = 1; cc < numPts; cc ++ )
|
|
{
|
|
totalCells ++;
|
|
}
|
|
}
|
|
*ost << totalCells << " 2" << endl;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
for ( cc = 1; cc < numPts; cc ++ )
|
|
{
|
|
vtkIdType point1 = pts[cc-1] + 1;
|
|
vtkIdType point2 = pts[cc] + 1;
|
|
*ost << point1 << " " << point2 << " " << material << " " << part << endl;
|
|
}
|
|
}
|
|
written = 1;
|
|
}
|
|
|
|
if ( data->GetPolys()->GetNumberOfCells() )
|
|
{
|
|
if ( written )
|
|
{
|
|
vtkErrorMacro("Multiple different cells in the poly data");
|
|
return 0;
|
|
}
|
|
ca = data->GetPolys();
|
|
numCells = ca->GetNumberOfCells();
|
|
vtkIdType numPts = 0;
|
|
vtkIdType *pts = NULL;
|
|
ca->InitTraversal();
|
|
ca->GetNextCell(numPts, pts);
|
|
totalCells ++;
|
|
vtkIdType numPoints = numPts;
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
if ( numPts != numPoints )
|
|
{
|
|
vtkErrorMacro("Found polygons with different order");
|
|
return 0;
|
|
}
|
|
totalCells ++;
|
|
}
|
|
*ost << totalCells << " " << numPoints << endl;
|
|
ca->InitTraversal();
|
|
int cnt = 0;
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
for ( cc = 0; cc < numPts; cc ++ )
|
|
{
|
|
vtkIdType pointindex = pts[cc] + 1;
|
|
*ost << pointindex << " ";
|
|
}
|
|
*ost << material << " " << part << endl;
|
|
cnt ++;
|
|
}
|
|
cout << "Written: " << cnt << " / " << numCells << " / " << totalCells << endl;
|
|
written = 1;
|
|
}
|
|
|
|
if ( data->GetStrips()->GetNumberOfCells() )
|
|
{
|
|
if ( written )
|
|
{
|
|
vtkErrorMacro("Multiple different cells in the poly data");
|
|
return 0;
|
|
}
|
|
ca = data->GetStrips();
|
|
numCells = ca->GetNumberOfCells();
|
|
vtkIdType numPts = 0;
|
|
vtkIdType *pts = NULL;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
// One triangle per cell
|
|
for ( cc = 2; cc < numPts; cc ++ )
|
|
{
|
|
totalCells ++;
|
|
}
|
|
}
|
|
*ost << totalCells << " 3" << endl;
|
|
ca->InitTraversal();
|
|
while ( ca->GetNextCell( numPts, pts ) )
|
|
{
|
|
for ( cc = 2; cc < numPts; cc ++ )
|
|
{
|
|
vtkIdType point1 = pts[cc-2] + 1;
|
|
vtkIdType point2 = pts[cc-1] + 1;
|
|
vtkIdType point3 = pts[cc] + 1;
|
|
*ost << point1 << " " << point2 << " " << point3 << " " << material << " " << part << endl;
|
|
}
|
|
}
|
|
written = 1;
|
|
}
|
|
|
|
return 1;
|
|
}
|
|
|
|
//----------------------------------------------------------------------------
|
|
int vtkFacetWriter::FillInputPortInformation(int port, vtkInformation *info)
|
|
{
|
|
if (!this->Superclass::FillInputPortInformation(port, info))
|
|
{
|
|
return 0;
|
|
}
|
|
info->Set(vtkAlgorithm::INPUT_IS_REPEATABLE(), 1);
|
|
return 1;
|
|
}
|
|
//----------------------------------------------------------------------------
|
|
void vtkFacetWriter::PrintSelf(ostream& os, vtkIndent indent)
|
|
{
|
|
this->Superclass::PrintSelf(os,indent);
|
|
|
|
os << indent << "File Name: "
|
|
<< (this->FileName ? this->FileName : "(none)") << "\n";
|
|
}
|
|
|
|
|