From e863ee991ade21ab822f0886eda36382bf50035d Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Wed, 16 Mar 2016 15:35:38 -0600 Subject: [PATCH 1/3] Change interface of VTKDataSetWriter Make it match VTKDataSetReader better. It's also a bit easier to use because you just have to give it a filename rather than open your own file stream. --- vtkm/cont/DataSet.h | 38 ++- vtkm/io/reader/VTKDataSetReader.h | 2 +- vtkm/io/writer/VTKDataSetWriter.h | 282 ++++++++++-------- .../testing/UnitTestVTKDataSetWriter.cxx | 52 +--- 4 files changed, 201 insertions(+), 173 deletions(-) diff --git a/vtkm/cont/DataSet.h b/vtkm/cont/DataSet.h index 40cb3a243..be24c9611 100644 --- a/vtkm/cont/DataSet.h +++ b/vtkm/cont/DataSet.h @@ -62,9 +62,10 @@ public: } VTKM_CONT_EXPORT - const vtkm::cont::Field &GetField(const std::string &name, + vtkm::Id GetFieldIndex( + const std::string &name, vtkm::cont::Field::AssociationEnum assoc = vtkm::cont::Field::ASSOC_ANY) - const + const { for (std::size_t i=0; i < this->Fields.size(); ++i) { @@ -72,12 +73,20 @@ public: assoc == this->Fields[i].GetAssociation()) && this->Fields[i].GetName() == name) { - return this->Fields[i]; + return static_cast(i); } } throw vtkm::cont::ErrorControlBadValue("No field with requested name: "+name); } + VTKM_CONT_EXPORT + const vtkm::cont::Field &GetField(const std::string &name, + vtkm::cont::Field::AssociationEnum assoc = vtkm::cont::Field::ASSOC_ANY) + const + { + return this->GetField(this->GetFieldIndex(name, assoc)); + } + VTKM_CONT_EXPORT void AddCoordinateSystem(vtkm::cont::CoordinateSystem cs) { @@ -94,20 +103,26 @@ public: } VTKM_CONT_EXPORT - const vtkm::cont::CoordinateSystem & - GetCoordinateSystem(const std::string &name) const + vtkm::Id GetCoordinateSystemIndex(const std::string &name) const { for (std::size_t i=0; i < this->CoordSystems.size(); ++i) { if (this->CoordSystems[i].GetName() == name) { - return this->CoordSystems[i]; + return static_cast(i); } } throw vtkm::cont::ErrorControlBadValue( "No coordinate system with requested name"); } + VTKM_CONT_EXPORT + const vtkm::cont::CoordinateSystem & + GetCoordinateSystem(const std::string &name) const + { + return this->GetCoordinateSystem(this->GetCoordinateSystemIndex(name)); + } + VTKM_CONT_EXPORT void AddCellSet(vtkm::cont::DynamicCellSet cellSet) { @@ -131,19 +146,24 @@ public: } VTKM_CONT_EXPORT - vtkm::cont::DynamicCellSet GetCellSet(const std::string &name) - const + vtkm::Id GetCellSetIndex(const std::string &name) const { for (std::size_t i=0; i < static_cast(this->GetNumberOfCellSets()); ++i) { if (this->CellSets[i].GetCellSet().GetName() == name) { - return this->CellSets[i]; + return static_cast(i); } } throw vtkm::cont::ErrorControlBadValue("No cell set with requested name"); } + VTKM_CONT_EXPORT + vtkm::cont::DynamicCellSet GetCellSet(const std::string &name) const + { + return this->GetCellSet(this->GetCellSetIndex(name)); + } + VTKM_CONT_EXPORT vtkm::IdComponent GetNumberOfCellSets() const { diff --git a/vtkm/io/reader/VTKDataSetReader.h b/vtkm/io/reader/VTKDataSetReader.h index e742446a9..7b13bdce6 100644 --- a/vtkm/io/reader/VTKDataSetReader.h +++ b/vtkm/io/reader/VTKDataSetReader.h @@ -37,7 +37,7 @@ namespace reader { class VTKDataSetReader : public VTKDataSetReaderBase { public: - VTKDataSetReader(const char *fileName) + explicit VTKDataSetReader(const char *fileName) : VTKDataSetReaderBase(fileName) { } diff --git a/vtkm/io/writer/VTKDataSetWriter.h b/vtkm/io/writer/VTKDataSetWriter.h index 277698ff2..c3ac6a3c6 100644 --- a/vtkm/io/writer/VTKDataSetWriter.h +++ b/vtkm/io/writer/VTKDataSetWriter.h @@ -20,6 +20,19 @@ #ifndef vtk_m_io_writer_DataSetWriter_h #define vtk_m_io_writer_DataSetWriter_h +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include + #include #include #include @@ -27,52 +40,11 @@ #include #include -#include -#include -#include -#include -#include -#include -#include +namespace vtkm { +namespace io { +namespace writer { -namespace { -#define VTK_EMPTY_CELL 0 -#define VTK_VERTEX 1 -#define VTK_POLY_VERTEX 2 -#define VTK_LINE 3 -#define VTK_POLY_LINE 4 -#define VTK_TRIANGLE 5 -#define VTK_TRIANGLE_STRIP 6 -#define VTK_POLYGON 7 -#define VTK_PIXEL 8 -#define VTK_QUAD 9 -#define VTK_TETRA 10 -#define VTK_VOXEL 11 -#define VTK_HEXAHEDRON 12 -#define VTK_WEDGE 13 -#define VTK_PYRAMID 14 -#define VTK_PENTAGONAL_PRISM 15 -#define VTK_HEXAGONAL_PRISM 16 - -int CellShapeToVTK(vtkm::Id type) -{ - switch(type) - { - case vtkm::CELL_SHAPE_VERTEX: return 1; - case vtkm::CELL_SHAPE_LINE: return 3; - case vtkm::CELL_SHAPE_TRIANGLE: return 5; - case vtkm::CELL_SHAPE_QUAD: return 9; - //case vtkm::CELL_SHAPE_PIXEL: return 8; - case vtkm::CELL_SHAPE_TETRA: return 10; - case vtkm::CELL_SHAPE_PYRAMID: return 14; - case vtkm::CELL_SHAPE_WEDGE: return 13; - case vtkm::CELL_SHAPE_HEXAHEDRON: return 12; - //case vtkm::CELL_SHAPE_VOXEL: return 11; - case vtkm::CELL_SHAPE_POLYGON: return 7; - } - - return 0; -} +namespace detail { struct OutputPointsFunctor { @@ -175,53 +147,48 @@ private: std::string *Name; }; -} - -namespace vtkm -{ -namespace io -{ -namespace writer -{ +} // namespace detail struct VTKDataSetWriter { private: static void WritePoints(std::ostream &out, - vtkm::cont::DataSet ds) + vtkm::cont::DataSet dataSet) { ///\todo: support other coordinate systems int cindex = 0; - vtkm::cont::CoordinateSystem coords = ds.GetCoordinateSystem(cindex); + vtkm::cont::CoordinateSystem coords = dataSet.GetCoordinateSystem(cindex); vtkm::cont::DynamicArrayHandleCoordinateSystem cdata = coords.GetData(); vtkm::Id npoints = cdata.GetNumberOfValues(); std::string typeName; - cdata.CastAndCall(GetDataTypeName(typeName)); + cdata.CastAndCall(detail::GetDataTypeName(typeName)); out << "POINTS " << npoints << " " << typeName << " " << std::endl; - cdata.CastAndCall(OutputPointsFunctor(out)); + cdata.CastAndCall(detail::OutputPointsFunctor(out)); } template static void WriteExplicitCells(std::ostream &out, - CellSetType cs) + CellSetType cellSet) { - vtkm::Id nCells = cs.GetNumberOfCells(); + vtkm::Id nCells = cellSet.GetNumberOfCells(); vtkm::Id conn_length = 0; for (vtkm::Id i=0; i ids; for (vtkm::Id i=0; i 4) - continue; + if (ncomps > 4) { continue; } if (!wrote_header) + { out << "POINT_DATA " << npoints << std::endl; - wrote_header = true; + wrote_header = true; + } std::string typeName; - field.GetData().CastAndCall(GetDataTypeName(typeName)); + field.GetData().CastAndCall(detail::GetDataTypeName(typeName)); - out << "SCALARS " << field.GetName() << " " << typeName << " " << ncomps << std::endl; + out << "SCALARS " << field.GetName() << " " + << typeName << " " << ncomps << std::endl; out << "LOOKUP_TABLE default" << std::endl; - field.GetData().CastAndCall(OutputFieldFunctor(out)); + field.GetData().CastAndCall(detail::OutputFieldFunctor(out)); } } static void WriteCellFields(std::ostream &out, - vtkm::cont::DataSet ds, - vtkm::cont::DynamicCellSet cs) + vtkm::cont::DataSet dataSet, + vtkm::cont::DynamicCellSet cellSet) { bool wrote_header = false; - for (vtkm::Id f = 0; f < ds.GetNumberOfFields(); f++) + for (vtkm::Id f = 0; f < dataSet.GetNumberOfFields(); f++) { - const vtkm::cont::Field field = ds.GetField(f); + const vtkm::cont::Field field = dataSet.GetField(f); if (field.GetAssociation() != vtkm::cont::Field::ASSOC_CELL_SET) + { continue; - if (field.GetAssocCellSet() != cs.GetCellSet().GetName()) + } + if (field.GetAssocCellSet() != cellSet.GetCellSet().GetName()) { continue; + } vtkm::Id ncells = field.GetData().GetNumberOfValues(); int ncomps = field.GetData().GetNumberOfComponents(); @@ -303,57 +274,62 @@ private: continue; if (!wrote_header) + { out << "CELL_DATA " << ncells << std::endl; - wrote_header = true; + wrote_header = true; + } std::string typeName; - field.GetData().CastAndCall(GetDataTypeName(typeName)); + field.GetData().CastAndCall(detail::GetDataTypeName(typeName)); - out << "SCALARS " << field.GetName() << " " << typeName << " " << ncomps << std::endl; + out << "SCALARS " << field.GetName() << " " + << typeName << " " << ncomps << std::endl; out << "LOOKUP_TABLE default" << std::endl; - field.GetData().CastAndCall(OutputFieldFunctor(out)); + field.GetData().CastAndCall(detail::OutputFieldFunctor(out)); } } static void WriteDataSetAsPoints(std::ostream &out, - vtkm::cont::DataSet ds) + vtkm::cont::DataSet dataSet) { out << "DATASET UNSTRUCTURED_GRID" << std::endl; - WritePoints(out, ds); - WriteVertexCells(out, ds); + WritePoints(out, dataSet); + WriteVertexCells(out, dataSet); } template static void WriteDataSetAsUnstructured(std::ostream &out, - vtkm::cont::DataSet ds, - CellSetType cs) + vtkm::cont::DataSet dataSet, + CellSetType cellSet) { out << "DATASET UNSTRUCTURED_GRID" << std::endl; - WritePoints(out, ds); - WriteExplicitCells(out, cs); + WritePoints(out, dataSet); + WriteExplicitCells(out, cellSet); } template - static void WriteDataSetAsStructured(std::ostream &out, - vtkm::cont::DataSet ds, - vtkm::cont::CellSetStructured cs) + static void WriteDataSetAsStructured( + std::ostream &out, + vtkm::cont::DataSet dataSet, + vtkm::cont::CellSetStructured cellSet) { ///\todo: support uniform/rectilinear out << "DATASET STRUCTURED_GRID" << std::endl; out << "DIMENSIONS "; - out << cs.GetPointDimensions()[0] << " "; - out << (DIM>1 ? cs.GetPointDimensions()[1] : 1) << " "; - out << (DIM>2 ? cs.GetPointDimensions()[2] : 1) << std::endl; + out << cellSet.GetPointDimensions()[0] << " "; + out << (DIM>1 ? cellSet.GetPointDimensions()[1] : 1) << " "; + out << (DIM>2 ? cellSet.GetPointDimensions()[2] : 1) << std::endl; - WritePoints(out, ds); + WritePoints(out, dataSet); } -public: - static void Write(std::ostream &out, vtkm::cont::DataSet ds, int csindex=0) + static void Write(std::ostream &out, + vtkm::cont::DataSet dataSet, + vtkm::Id csindex=0) { - VTKM_ASSERT_CONT(csindex < ds.GetNumberOfCellSets()); + VTKM_ASSERT_CONT(csindex < dataSet.GetNumberOfCellSets()); out << "# vtk DataFile Version 3.0" << std::endl; out << "vtk output" << std::endl; @@ -361,49 +337,103 @@ public: if (csindex < 0) { - WriteDataSetAsPoints(out, ds); - WritePointFields(out, ds); + WriteDataSetAsPoints(out, dataSet); + WritePointFields(out, dataSet); } else { - vtkm::cont::DynamicCellSet cs = ds.GetCellSet(csindex); - if (cs.IsType >()) + vtkm::cont::DynamicCellSet cellSet = dataSet.GetCellSet(csindex); + if (cellSet.IsType >()) { WriteDataSetAsUnstructured(out, - ds, - cs.Cast >()); + dataSet, + cellSet.Cast >()); } - else if (cs.IsType >()) + else if (cellSet.IsType >()) { WriteDataSetAsStructured(out, - ds, - cs.Cast >()); + dataSet, + cellSet.Cast >()); } - else if (cs.IsType >()) + else if (cellSet.IsType >()) { WriteDataSetAsStructured(out, - ds, - cs.Cast >()); + dataSet, + cellSet.Cast >()); } - else if (cs.IsType >()) + else if (cellSet.IsType >()) { // these function just like explicit cell sets WriteDataSetAsUnstructured(out, - ds, - cs.Cast >()); + dataSet, + cellSet.Cast >()); } else { VTKM_ASSERT_CONT(false); } - WritePointFields(out, ds); - WriteCellFields(out, ds, cs); + WritePointFields(out, dataSet); + WriteCellFields(out, dataSet, cellSet); } } +public: + VTKM_CONT_EXPORT + explicit VTKDataSetWriter(const std::string &filename) + : FileName(filename) { } + + VTKM_CONT_EXPORT + void WriteDataSet(vtkm::cont::DataSet dataSet, + vtkm::Id cellSetIndex = 0) const + { + if (cellSetIndex >= dataSet.GetNumberOfCellSets()) + { + if (cellSetIndex == 0) + { + // Special case where there are no cell sets. In this case, write out + // the data as points. + cellSetIndex = -1; + } + else + { + throw vtkm::cont::ErrorControlBadValue( + "Selected invalid cell set index."); + } + } + + if (dataSet.GetNumberOfCoordinateSystems() < 1) + { + throw vtkm::cont::ErrorControlBadValue( + "DataSet has no coordinate system, which is not supported by VTK file format."); + } + + try + { + std::ofstream fileStream(this->FileName, std::fstream::trunc); + this->Write(fileStream, dataSet, cellSetIndex); + fileStream.close(); + } + catch (std::ofstream::failure error) + { + throw vtkm::io::ErrorIO(error.what()); + } + } + + VTKM_CONT_EXPORT + void WriteDataSet(vtkm::cont::DataSet dataSet, + const std::string &cellSetName) + { + this->WriteDataSet(dataSet, dataSet.GetCellSetIndex(cellSetName)); + } + +private: + std::string FileName; + }; //struct VTKDataSetWriter -}}} //namespace vtkm::io::writer +} +} +} //namespace vtkm::io::writer #endif //vtk_m_io_writer_DataSetWriter_h diff --git a/vtkm/io/writer/testing/UnitTestVTKDataSetWriter.cxx b/vtkm/io/writer/testing/UnitTestVTKDataSetWriter.cxx index ddeb64ab2..abe8ea622 100644 --- a/vtkm/io/writer/testing/UnitTestVTKDataSetWriter.cxx +++ b/vtkm/io/writer/testing/UnitTestVTKDataSetWriter.cxx @@ -18,66 +18,44 @@ // this software. //============================================================================ -#include -#include -#include -#include -#include +#include -#include -#include #include #include -#include - namespace { void TestVTKExplicitWrite() { vtkm::cont::testing::MakeTestDataSet tds; - std::ofstream out1("fileA1.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out1, - tds.Make3DExplicitDataSet0()); - out1.close(); + vtkm::io::writer::VTKDataSetWriter writer1("fileA1.vtk"); + writer1.WriteDataSet(tds.Make3DExplicitDataSet0()); // force it to output an explicit grid as points - std::ofstream out2("fileA2.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out2, - tds.Make3DExplicitDataSet0(), -1); - out2.close(); + vtkm::io::writer::VTKDataSetWriter writer2("fileA2.vtk"); + writer2.WriteDataSet(tds.Make3DExplicitDataSet0(), -1); - std::ofstream out3("fileA3.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out3, - tds.Make3DExplicitDataSet0()); - out3.close(); + vtkm::io::writer::VTKDataSetWriter writer3("fileA3.vtk"); + writer3.WriteDataSet(tds.Make3DExplicitDataSet0()); - std::ofstream out4("fileA4.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out4, - tds.Make3DExplicitDataSetCowNose()); - out4.close(); + vtkm::io::writer::VTKDataSetWriter writer4("fileA4.vtk"); + writer4.WriteDataSet(tds.Make3DExplicitDataSetCowNose()); } void TestVTKUniformWrite() { vtkm::cont::testing::MakeTestDataSet tds; - std::ofstream out1("fileB1.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out1, - tds.Make2DUniformDataSet0()); - out1.close(); + vtkm::io::writer::VTKDataSetWriter writer1("fileB1.vtk"); + writer1.WriteDataSet(tds.Make2DUniformDataSet0()); - std::ofstream out2("fileB2.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out2, - tds.Make3DUniformDataSet0()); - out2.close(); + vtkm::io::writer::VTKDataSetWriter writer2("fileB2.vtk"); + writer2.WriteDataSet(tds.Make3DUniformDataSet0()); // force it to output an explicit grid as points - std::ofstream out3("fileB3.vtk"); - vtkm::io::writer::VTKDataSetWriter::Write(out3, - tds.Make3DUniformDataSet0(), -1); - out3.close(); + vtkm::io::writer::VTKDataSetWriter writer3("fileB3.vtk"); + writer3.WriteDataSet(tds.Make3DUniformDataSet0(), -1); } void TestVTKWrite() From 6aaf85baa65a85644026188213d852dd8f211b1b Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 17 Mar 2016 08:53:35 -0600 Subject: [PATCH 2/3] Fix compile error with ofstream. Not all STD implementations allow constructing an ofstream with a filename in a std::string. Get the c string instead. --- vtkm/io/writer/VTKDataSetWriter.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vtkm/io/writer/VTKDataSetWriter.h b/vtkm/io/writer/VTKDataSetWriter.h index c3ac6a3c6..4d86abd53 100644 --- a/vtkm/io/writer/VTKDataSetWriter.h +++ b/vtkm/io/writer/VTKDataSetWriter.h @@ -410,7 +410,7 @@ public: try { - std::ofstream fileStream(this->FileName, std::fstream::trunc); + std::ofstream fileStream(this->FileName.c_str(), std::fstream::trunc); this->Write(fileStream, dataSet, cellSetIndex); fileStream.close(); } From f81e8c642fa338cc9df16820b7c071c09bf23b77 Mon Sep 17 00:00:00 2001 From: Kenneth Moreland Date: Thu, 17 Mar 2016 09:13:25 -0600 Subject: [PATCH 3/3] Fix example that was using the old interface to VTKDataSetWriter As a bonus, fix a compiler warning about an unused typedef. --- examples/clipping/Clipping.cxx | 5 ++--- examples/isosurface/IsosurfaceUniformGrid.cxx | 2 -- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/clipping/Clipping.cxx b/examples/clipping/Clipping.cxx index 609a25830..64c8ca53f 100644 --- a/examples/clipping/Clipping.cxx +++ b/examples/clipping/Clipping.cxx @@ -105,9 +105,8 @@ int main(int argc, char *argv[]) << "process scalars: " << processScalarsTime << std::endl << "Total: " << totalTime << std::endl; - std::ofstream outFile(argv[argc - 1]); - vtkm::io::writer::VTKDataSetWriter::Write(outFile, output); - outFile.close(); + vtkm::io::writer::VTKDataSetWriter writer(argv[argc - 1]); + writer.WriteDataSet(output); return 0; } diff --git a/examples/isosurface/IsosurfaceUniformGrid.cxx b/examples/isosurface/IsosurfaceUniformGrid.cxx index 4dba1c72e..11250eb4b 100644 --- a/examples/isosurface/IsosurfaceUniformGrid.cxx +++ b/examples/isosurface/IsosurfaceUniformGrid.cxx @@ -230,8 +230,6 @@ void mouseCall(int button, int state, int x, int y) // Compute and render an isosurface for a uniform grid example int main(int argc, char* argv[]) { - typedef vtkm::cont::CellSetStructured<3> CellSet; - vtkm::cont::DataSet dataSet = MakeIsosurfaceTestDataSet(dims); vtkm::filter::MarchingCubes filter;