2020-05-19 19:29:04 +00:00
|
|
|
//============================================================================
|
|
|
|
// Copyright (c) Kitware, Inc.
|
|
|
|
// All rights reserved.
|
|
|
|
// See LICENSE.txt 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 <vtkm/io/VTKDataSetWriter.h>
|
|
|
|
|
|
|
|
#include <vtkm/CellShape.h>
|
|
|
|
|
|
|
|
#include <vtkm/cont/CellSetExplicit.h>
|
|
|
|
#include <vtkm/cont/CellSetSingleType.h>
|
|
|
|
#include <vtkm/cont/CellSetStructured.h>
|
|
|
|
#include <vtkm/cont/ErrorBadType.h>
|
|
|
|
#include <vtkm/cont/ErrorBadValue.h>
|
|
|
|
#include <vtkm/cont/Field.h>
|
|
|
|
|
|
|
|
#include <vtkm/io/ErrorIO.h>
|
|
|
|
|
|
|
|
#include <vtkm/io/internal/VTKDataSetTypes.h>
|
|
|
|
|
|
|
|
#include <algorithm>
|
|
|
|
#include <cctype>
|
|
|
|
#include <cstring>
|
|
|
|
#include <fstream>
|
2020-11-20 18:46:59 +00:00
|
|
|
#include <iomanip>
|
2020-05-19 19:29:04 +00:00
|
|
|
#include <iostream>
|
2021-02-26 21:49:42 +00:00
|
|
|
#include <sstream>
|
2020-05-19 19:29:04 +00:00
|
|
|
#include <string>
|
|
|
|
#include <vector>
|
|
|
|
|
|
|
|
namespace
|
|
|
|
{
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
struct CallForBaseTypeFunctor
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
template <typename T, typename Functor, typename... Args>
|
|
|
|
void operator()(T t,
|
|
|
|
bool& success,
|
|
|
|
Functor functor,
|
|
|
|
const vtkm::cont::UnknownArrayHandle& array,
|
|
|
|
Args&&... args)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
if (!array.IsBaseComponentType<T>())
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
success = true;
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
functor(t, array, std::forward<Args>(args)...);
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
2020-12-16 00:22:03 +00:00
|
|
|
};
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
template <typename Functor, typename... Args>
|
|
|
|
void CallForBaseType(Functor&& functor, const vtkm::cont::UnknownArrayHandle& array, Args&&... args)
|
|
|
|
{
|
|
|
|
bool success = true;
|
|
|
|
vtkm::ListForEach(CallForBaseTypeFunctor{},
|
|
|
|
vtkm::TypeListScalarAll{},
|
|
|
|
success,
|
|
|
|
std::forward<Functor>(functor),
|
|
|
|
array,
|
|
|
|
std::forward<Args>(args)...);
|
|
|
|
if (!success)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
std::ostringstream out;
|
|
|
|
out << "Unrecognized base type in array to be written out.\nArray: ";
|
|
|
|
array.PrintSummary(out);
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
throw vtkm::cont::ErrorBadValue(out.str());
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
2020-12-16 00:22:03 +00:00
|
|
|
}
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
template <typename T>
|
|
|
|
using ArrayHandleRectilinearCoordinates =
|
|
|
|
vtkm::cont::ArrayHandleCartesianProduct<vtkm::cont::ArrayHandle<T>,
|
|
|
|
vtkm::cont::ArrayHandle<T>,
|
|
|
|
vtkm::cont::ArrayHandle<T>>;
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
struct OutputArrayDataFunctor
|
|
|
|
{
|
|
|
|
template <typename T>
|
|
|
|
VTKM_CONT void operator()(T, const vtkm::cont::UnknownArrayHandle& array, std::ostream& out) const
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-23 18:36:15 +00:00
|
|
|
auto componentArray = array.ExtractArrayFromComponents<T>();
|
|
|
|
auto portal = componentArray.ReadPortal();
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
vtkm::Id numValues = portal.GetNumberOfValues();
|
|
|
|
for (vtkm::Id valueIndex = 0; valueIndex < numValues; ++valueIndex)
|
|
|
|
{
|
|
|
|
auto value = portal.Get(valueIndex);
|
|
|
|
for (vtkm::IdComponent cIndex = 0; cIndex < value.GetNumberOfComponents(); ++cIndex)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
out << ((cIndex == 0) ? "" : " ") << value[cIndex];
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
2020-12-16 00:22:03 +00:00
|
|
|
out << "\n";
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
void OutputArrayData(const vtkm::cont::UnknownArrayHandle& array, std::ostream& out)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
CallForBaseType(OutputArrayDataFunctor{}, array, out);
|
|
|
|
}
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
struct GetFieldTypeNameFunctor
|
|
|
|
{
|
|
|
|
template <typename Type>
|
|
|
|
void operator()(Type, const vtkm::cont::UnknownArrayHandle& array, std::string& name) const
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-12-16 00:22:03 +00:00
|
|
|
if (array.IsBaseComponentType<Type>())
|
|
|
|
{
|
|
|
|
name = vtkm::io::internal::DataTypeName<Type>::Name();
|
|
|
|
}
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::string GetFieldTypeName(const vtkm::cont::UnknownArrayHandle& array)
|
|
|
|
{
|
|
|
|
std::string name;
|
|
|
|
CallForBaseType(GetFieldTypeNameFunctor{}, array, name);
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
2020-07-09 01:12:14 +00:00
|
|
|
template <vtkm::IdComponent DIM>
|
|
|
|
void WriteDimensions(std::ostream& out, const vtkm::cont::CellSetStructured<DIM>& cellSet)
|
|
|
|
{
|
|
|
|
auto pointDimensions = cellSet.GetPointDimensions();
|
|
|
|
using VTraits = vtkm::VecTraits<decltype(pointDimensions)>;
|
|
|
|
|
|
|
|
out << "DIMENSIONS ";
|
|
|
|
out << VTraits::GetComponent(pointDimensions, 0) << " ";
|
|
|
|
out << (DIM > 1 ? VTraits::GetComponent(pointDimensions, 1) : 1) << " ";
|
|
|
|
out << (DIM > 2 ? VTraits::GetComponent(pointDimensions, 2) : 1) << "\n";
|
|
|
|
}
|
|
|
|
|
2020-05-19 19:29:04 +00:00
|
|
|
void WritePoints(std::ostream& out, const vtkm::cont::DataSet& dataSet)
|
|
|
|
{
|
|
|
|
///\todo: support other coordinate systems
|
|
|
|
int cindex = 0;
|
|
|
|
auto cdata = dataSet.GetCoordinateSystem(cindex).GetData();
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::string typeName = GetFieldTypeName(cdata);
|
2020-07-09 18:56:23 +00:00
|
|
|
|
2020-05-19 19:29:04 +00:00
|
|
|
vtkm::Id npoints = cdata.GetNumberOfValues();
|
2020-07-09 18:56:23 +00:00
|
|
|
out << "POINTS " << npoints << " " << typeName << " " << '\n';
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(cdata, out);
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <class CellSetType>
|
|
|
|
void WriteExplicitCells(std::ostream& out, const CellSetType& cellSet)
|
|
|
|
{
|
|
|
|
vtkm::Id nCells = cellSet.GetNumberOfCells();
|
|
|
|
|
|
|
|
vtkm::Id conn_length = 0;
|
|
|
|
for (vtkm::Id i = 0; i < nCells; ++i)
|
|
|
|
{
|
|
|
|
conn_length += 1 + cellSet.GetNumberOfPointsInCell(i);
|
|
|
|
}
|
|
|
|
|
|
|
|
out << "CELLS " << nCells << " " << conn_length << '\n';
|
|
|
|
|
|
|
|
for (vtkm::Id i = 0; i < nCells; ++i)
|
|
|
|
{
|
|
|
|
vtkm::cont::ArrayHandle<vtkm::Id> ids;
|
|
|
|
vtkm::Id nids = cellSet.GetNumberOfPointsInCell(i);
|
|
|
|
cellSet.GetIndices(i, ids);
|
|
|
|
out << nids;
|
|
|
|
auto IdPortal = ids.ReadPortal();
|
|
|
|
for (int j = 0; j < nids; ++j)
|
|
|
|
out << " " << IdPortal.Get(j);
|
|
|
|
out << '\n';
|
|
|
|
}
|
|
|
|
|
|
|
|
out << "CELL_TYPES " << nCells << '\n';
|
|
|
|
for (vtkm::Id i = 0; i < nCells; ++i)
|
|
|
|
{
|
|
|
|
vtkm::Id shape = cellSet.GetCellShape(i);
|
|
|
|
out << shape << '\n';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void WritePointFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
|
|
|
|
{
|
|
|
|
bool wrote_header = false;
|
|
|
|
for (vtkm::Id f = 0; f < dataSet.GetNumberOfFields(); f++)
|
|
|
|
{
|
|
|
|
const vtkm::cont::Field field = dataSet.GetField(f);
|
|
|
|
|
|
|
|
if (field.GetAssociation() != vtkm::cont::Field::Association::POINTS)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
vtkm::Id npoints = field.GetNumberOfValues();
|
2020-12-16 00:22:03 +00:00
|
|
|
int ncomps = field.GetData().GetNumberOfComponentsFlat();
|
2020-05-19 19:29:04 +00:00
|
|
|
|
|
|
|
if (!wrote_header)
|
|
|
|
{
|
|
|
|
out << "POINT_DATA " << npoints << '\n';
|
|
|
|
wrote_header = true;
|
|
|
|
}
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::string typeName = GetFieldTypeName(field.GetData());
|
2020-05-19 19:29:04 +00:00
|
|
|
std::string name = field.GetName();
|
|
|
|
for (auto& c : name)
|
|
|
|
{
|
|
|
|
if (std::isspace(c))
|
|
|
|
{
|
|
|
|
c = '_';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
out << "SCALARS " << name << " " << typeName << " " << ncomps << '\n';
|
|
|
|
out << "LOOKUP_TABLE default" << '\n';
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(field.GetData(), out);
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void WriteCellFields(std::ostream& out, const vtkm::cont::DataSet& dataSet)
|
|
|
|
{
|
|
|
|
bool wrote_header = false;
|
|
|
|
for (vtkm::Id f = 0; f < dataSet.GetNumberOfFields(); f++)
|
|
|
|
{
|
|
|
|
const vtkm::cont::Field field = dataSet.GetField(f);
|
|
|
|
if (!field.IsFieldCell())
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
vtkm::Id ncells = field.GetNumberOfValues();
|
2020-12-16 00:22:03 +00:00
|
|
|
int ncomps = field.GetData().GetNumberOfComponentsFlat();
|
2020-05-19 19:29:04 +00:00
|
|
|
|
|
|
|
if (!wrote_header)
|
|
|
|
{
|
|
|
|
out << "CELL_DATA " << ncells << '\n';
|
|
|
|
wrote_header = true;
|
|
|
|
}
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
std::string typeName = GetFieldTypeName(field.GetData());
|
2020-05-19 19:29:04 +00:00
|
|
|
|
|
|
|
std::string name = field.GetName();
|
|
|
|
for (auto& c : name)
|
|
|
|
{
|
|
|
|
if (std::isspace(c))
|
|
|
|
{
|
|
|
|
c = '_';
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
out << "SCALARS " << name << " " << typeName << " " << ncomps << '\n';
|
|
|
|
out << "LOOKUP_TABLE default" << '\n';
|
|
|
|
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(field.GetData(), out);
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
template <class CellSetType>
|
|
|
|
void WriteDataSetAsUnstructured(std::ostream& out,
|
|
|
|
const vtkm::cont::DataSet& dataSet,
|
|
|
|
const CellSetType& cellSet)
|
|
|
|
{
|
|
|
|
out << "DATASET UNSTRUCTURED_GRID" << '\n';
|
|
|
|
WritePoints(out, dataSet);
|
|
|
|
WriteExplicitCells(out, cellSet);
|
|
|
|
}
|
|
|
|
|
|
|
|
template <vtkm::IdComponent DIM>
|
2020-07-09 01:12:14 +00:00
|
|
|
void WriteDataSetAsStructuredPoints(std::ostream& out,
|
|
|
|
const vtkm::cont::ArrayHandleUniformPointCoordinates& points,
|
|
|
|
const vtkm::cont::CellSetStructured<DIM>& cellSet)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-07-09 01:12:14 +00:00
|
|
|
out << "DATASET STRUCTURED_POINTS\n";
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-07-09 01:12:14 +00:00
|
|
|
WriteDimensions(out, cellSet);
|
2020-05-19 19:29:04 +00:00
|
|
|
|
2020-07-09 01:12:14 +00:00
|
|
|
auto portal = points.ReadPortal();
|
|
|
|
auto origin = portal.GetOrigin();
|
|
|
|
auto spacing = portal.GetSpacing();
|
|
|
|
out << "ORIGIN " << origin[0] << " " << origin[1] << " " << origin[2] << "\n";
|
|
|
|
out << "SPACING " << spacing[0] << " " << spacing[1] << " " << spacing[2] << "\n";
|
|
|
|
}
|
|
|
|
|
|
|
|
template <typename T, vtkm::IdComponent DIM>
|
|
|
|
void WriteDataSetAsRectilinearGrid(std::ostream& out,
|
|
|
|
const ArrayHandleRectilinearCoordinates<T>& points,
|
|
|
|
const vtkm::cont::CellSetStructured<DIM>& cellSet)
|
|
|
|
{
|
|
|
|
out << "DATASET RECTILINEAR_GRID\n";
|
|
|
|
|
|
|
|
WriteDimensions(out, cellSet);
|
|
|
|
|
|
|
|
std::string typeName = vtkm::io::internal::DataTypeName<T>::Name();
|
|
|
|
vtkm::cont::ArrayHandle<T> dimArray;
|
|
|
|
|
2020-11-17 15:30:30 +00:00
|
|
|
dimArray = points.GetFirstArray();
|
2020-07-09 01:12:14 +00:00
|
|
|
out << "X_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(dimArray, out);
|
2020-07-09 01:12:14 +00:00
|
|
|
|
2020-11-17 15:30:30 +00:00
|
|
|
dimArray = points.GetSecondArray();
|
2020-07-09 01:12:14 +00:00
|
|
|
out << "Y_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(dimArray, out);
|
2020-07-09 01:12:14 +00:00
|
|
|
|
2020-11-17 15:30:30 +00:00
|
|
|
dimArray = points.GetThirdArray();
|
2020-07-09 01:12:14 +00:00
|
|
|
out << "Z_COORDINATES " << dimArray.GetNumberOfValues() << " " << typeName << "\n";
|
2020-12-16 00:22:03 +00:00
|
|
|
OutputArrayData(dimArray, out);
|
2020-07-09 01:12:14 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
template <vtkm::IdComponent DIM>
|
|
|
|
void WriteDataSetAsStructuredGrid(std::ostream& out,
|
|
|
|
const vtkm::cont::DataSet& dataSet,
|
|
|
|
const vtkm::cont::CellSetStructured<DIM>& cellSet)
|
|
|
|
{
|
|
|
|
out << "DATASET STRUCTURED_GRID" << '\n';
|
|
|
|
|
|
|
|
WriteDimensions(out, cellSet);
|
2020-05-19 19:29:04 +00:00
|
|
|
|
|
|
|
WritePoints(out, dataSet);
|
|
|
|
}
|
|
|
|
|
2020-07-09 01:12:14 +00:00
|
|
|
template <vtkm::IdComponent DIM>
|
|
|
|
void WriteDataSetAsStructured(std::ostream& out,
|
|
|
|
const vtkm::cont::DataSet& dataSet,
|
|
|
|
const vtkm::cont::CellSetStructured<DIM>& cellSet)
|
|
|
|
{
|
|
|
|
///\todo: support rectilinear
|
|
|
|
|
|
|
|
// Type of structured grid (uniform, rectilinear, curvilinear) is determined by coordinate system
|
2020-06-30 21:14:35 +00:00
|
|
|
auto coordSystem = dataSet.GetCoordinateSystem().GetData();
|
2020-07-09 01:12:14 +00:00
|
|
|
if (coordSystem.IsType<vtkm::cont::ArrayHandleUniformPointCoordinates>())
|
|
|
|
{
|
|
|
|
// uniform is written as "structured points"
|
|
|
|
WriteDataSetAsStructuredPoints(
|
2021-01-25 17:36:56 +00:00
|
|
|
out, coordSystem.AsArrayHandle<vtkm::cont::ArrayHandleUniformPointCoordinates>(), cellSet);
|
2020-07-09 01:12:14 +00:00
|
|
|
}
|
|
|
|
else if (coordSystem.IsType<ArrayHandleRectilinearCoordinates<vtkm::Float32>>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsRectilinearGrid(
|
2021-01-25 17:36:56 +00:00
|
|
|
out, coordSystem.AsArrayHandle<ArrayHandleRectilinearCoordinates<vtkm::Float32>>(), cellSet);
|
2020-07-09 01:12:14 +00:00
|
|
|
}
|
|
|
|
else if (coordSystem.IsType<ArrayHandleRectilinearCoordinates<vtkm::Float64>>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsRectilinearGrid(
|
2021-01-25 17:36:56 +00:00
|
|
|
out, coordSystem.AsArrayHandle<ArrayHandleRectilinearCoordinates<vtkm::Float64>>(), cellSet);
|
2020-07-09 01:12:14 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
// Curvilinear is written as "structured grid"
|
|
|
|
WriteDataSetAsStructuredGrid(out, dataSet, cellSet);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-24 19:42:39 +00:00
|
|
|
void Write(std::ostream& out, const vtkm::cont::DataSet& dataSet)
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
|
|
|
// The Paraview parser cannot handle scientific notation:
|
|
|
|
out << std::fixed;
|
2020-11-20 16:39:30 +00:00
|
|
|
// This causes a big problem for the dataset writer.
|
|
|
|
// Fixed point and floating point are fundamentally different.
|
|
|
|
// This is a workaround, but until Paraview supports parsing floats,
|
|
|
|
// this is as good as we can do.
|
|
|
|
#ifdef VTKM_USE_DOUBLE_PRECISION
|
|
|
|
out << std::setprecision(18);
|
|
|
|
#else
|
|
|
|
out << std::setprecision(10);
|
|
|
|
#endif
|
2020-05-19 19:29:04 +00:00
|
|
|
out << "# vtk DataFile Version 3.0" << '\n';
|
|
|
|
out << "vtk output" << '\n';
|
|
|
|
out << "ASCII" << '\n';
|
|
|
|
|
2020-07-24 19:42:39 +00:00
|
|
|
vtkm::cont::DynamicCellSet cellSet = dataSet.GetCellSet();
|
|
|
|
if (cellSet.IsType<vtkm::cont::CellSetExplicit<>>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsUnstructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetExplicit<>>());
|
|
|
|
}
|
|
|
|
else if (cellSet.IsType<vtkm::cont::CellSetStructured<1>>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsStructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetStructured<1>>());
|
|
|
|
}
|
|
|
|
else if (cellSet.IsType<vtkm::cont::CellSetStructured<2>>())
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
2020-07-24 19:42:39 +00:00
|
|
|
WriteDataSetAsStructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetStructured<2>>());
|
|
|
|
}
|
|
|
|
else if (cellSet.IsType<vtkm::cont::CellSetStructured<3>>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsStructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetStructured<3>>());
|
|
|
|
}
|
|
|
|
else if (cellSet.IsType<vtkm::cont::CellSetSingleType<>>())
|
|
|
|
{
|
|
|
|
// these function just like explicit cell sets
|
|
|
|
WriteDataSetAsUnstructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetSingleType<>>());
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
2021-03-08 15:18:42 +00:00
|
|
|
else if (cellSet.IsType<vtkm::cont::CellSetExtrude>())
|
|
|
|
{
|
|
|
|
WriteDataSetAsUnstructured(out, dataSet, cellSet.Cast<vtkm::cont::CellSetExplicit<>>());
|
|
|
|
}
|
2020-05-19 19:29:04 +00:00
|
|
|
else
|
|
|
|
{
|
2020-07-24 19:42:39 +00:00
|
|
|
throw vtkm::cont::ErrorBadType("Could not determine type to write out.");
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
2020-07-24 19:42:39 +00:00
|
|
|
|
|
|
|
WritePointFields(out, dataSet);
|
|
|
|
WriteCellFields(out, dataSet);
|
2020-05-19 19:29:04 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
} // anonymous namespace
|
|
|
|
|
|
|
|
namespace vtkm
|
|
|
|
{
|
|
|
|
namespace io
|
|
|
|
{
|
|
|
|
|
|
|
|
VTKDataSetWriter::VTKDataSetWriter(const char* fileName)
|
|
|
|
: FileName(fileName)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
VTKDataSetWriter::VTKDataSetWriter(const std::string& fileName)
|
|
|
|
: FileName(fileName)
|
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2020-07-24 19:42:39 +00:00
|
|
|
void VTKDataSetWriter::WriteDataSet(const vtkm::cont::DataSet& dataSet) const
|
2020-05-19 19:29:04 +00:00
|
|
|
{
|
|
|
|
if (dataSet.GetNumberOfCoordinateSystems() < 1)
|
|
|
|
{
|
|
|
|
throw vtkm::cont::ErrorBadValue(
|
|
|
|
"DataSet has no coordinate system, which is not supported by VTK file format.");
|
|
|
|
}
|
|
|
|
try
|
|
|
|
{
|
|
|
|
std::ofstream fileStream(this->FileName.c_str(), std::fstream::trunc);
|
2020-07-24 19:42:39 +00:00
|
|
|
Write(fileStream, dataSet);
|
2020-05-19 19:29:04 +00:00
|
|
|
fileStream.close();
|
|
|
|
}
|
|
|
|
catch (std::ofstream::failure& error)
|
|
|
|
{
|
|
|
|
throw vtkm::io::ErrorIO(error.what());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} // namespace vtkm::io
|