[cig-commits] r13634 - cs/cigma/trunk/src

luis at geodynamics.org luis at geodynamics.org
Tue Dec 9 18:16:37 PST 2008


Author: luis
Date: 2008-12-09 18:16:36 -0800 (Tue, 09 Dec 2008)
New Revision: 13634

Added:
   cs/cigma/trunk/src/io_vtk.cpp
   cs/cigma/trunk/src/io_vtk.h
Log:
Added io_vtk.{h,cpp}, which refactors common code in reader/writer classes

Added: cs/cigma/trunk/src/io_vtk.cpp
===================================================================
--- cs/cigma/trunk/src/io_vtk.cpp	                        (rev 0)
+++ cs/cigma/trunk/src/io_vtk.cpp	2008-12-10 02:16:36 UTC (rev 13634)
@@ -0,0 +1,177 @@
+#ifdef HAVE_VTK
+#include "io_vtk.h"
+#include "Filesystem.h"
+
+using namespace std;
+using namespace cigma;
+
+
+/* datatypes returned by GetDataType method */
+template <> int vtk_datatype_from<void>()           { return VTK_VOID; }
+template <> int vtk_datatype_from<char>()           { return VTK_CHAR; }
+template <> int vtk_datatype_from<signed char>()    { return VTK_SIGNED_CHAR; }
+template <> int vtk_datatype_from<unsigned char>()  { return VTK_UNSIGNED_CHAR; }
+template <> int vtk_datatype_from<short>()          { return VTK_SHORT; }
+template <> int vtk_datatype_from<unsigned short>() { return VTK_UNSIGNED_SHORT; }
+template <> int vtk_datatype_from<int>()            { return VTK_INT; }
+template <> int vtk_datatype_from<unsigned int>()   { return VTK_UNSIGNED_INT; }
+template <> int vtk_datatype_from<long>()           { return VTK_LONG; }
+template <> int vtk_datatype_from<unsigned long>()  { return VTK_UNSIGNED_LONG; }
+template <> int vtk_datatype_from<float>()          { return VTK_FLOAT; }
+template <> int vtk_datatype_from<double>()         { return VTK_DOUBLE; }
+template <> int vtk_datatype_from<vtkIdType>()      { return VTK_ID_TYPE; }
+
+/* convert datatype to a string */
+std::string vtk_datatype_name(int datatype)
+{
+    switch (datatype)
+    {
+    case VTK_VOID:              return "void";
+    case VTK_CHAR:              return "char";
+    case VTK_SIGNED_CHAR:       return "signed char";
+    case VTK_UNSIGNED_CHAR:     return "unsigned char";
+    case VTK_SHORT:             return "short";
+    case VTK_UNSIGNED_SHORT:    return "unsigned short";
+    case VTK_INT:               return "int";
+    case VTK_UNSIGNED_INT:      return "unsigned int";
+    case VTK_LONG:              return "long";
+    case VTK_UNSIGNED_LONG:     return "unsigned long";
+    case VTK_FLOAT:             return "float";
+    case VTK_DOUBLE:            return "double";
+    case VTK_ID_TYPE:           return "vtkIdType";
+    default:
+        if (true)
+        {
+            std::ostringstream stream;
+            stream << "No name for datatype " << datatype << std::ends;
+            throw cigma::Exception("vtk_datatype_name", stream.str());
+        }
+    }
+
+    return "";
+}
+
+
+/* create a legacy reader */
+vtkDataSetReader* vtk_open(const char *filename, vtkGridType& gridType)
+{
+    TRI_LOG_STR("vtk_open()");
+    TRI_LOG(filename);
+
+    vtkDataSetReader* legacyReader;
+    int status;
+    
+    legacyReader = vtkDataSetReader::New();
+    legacyReader->SetFileName(filename);
+    status = legacyReader->OpenVTKFile();
+
+    if (status != 0)
+    {
+        gridType = GRID_VTK;
+        legacyReader->Update();
+    }
+    else
+    {
+        gridType = GRID_NULL;
+        return 0;
+    }
+
+    return legacyReader;
+}
+
+
+/* create an xml reader */
+vtkXMLReader* vtk_open_xml(const char *filename, vtkGridType& gridType)
+{
+    TRI_LOG_STR("vtk_open_xml()");
+    TRI_LOG(filename);
+
+    namespace fs = boost::filesystem;
+    string path(filename);
+    string ext = fs::extension(path);
+
+    vtkXMLReader* xmlReader;
+
+    if (ext == ".vtr")
+    {
+        xmlReader = vtkXMLRectilinearGridReader::New();
+        gridType  = GRID_VTR;
+    }
+    else if (ext == ".vts")
+    {
+        xmlReader = vtkXMLStructuredGridReader::New();
+        gridType  = GRID_VTS;
+    }
+    else if (ext == ".vtu")
+    {
+        xmlReader = vtkXMLUnstructuredGridReader::New();
+        gridType  = GRID_VTU;
+    }
+    else if (ext == ".pvtr")
+    {
+        xmlReader = vtkXMLPRectilinearGridReader::New();
+        gridType  = GRID_PVTR;
+    }
+    else if (ext == ".pvts")
+    {
+        xmlReader = vtkXMLPStructuredGridReader::New();
+        gridType  = GRID_PVTS;
+    }
+    else if (ext == ".pvtu")
+    {
+        xmlReader = vtkXMLPUnstructuredGridReader::New();
+        gridType  = GRID_PVTU;
+    }
+    else
+    {
+        xmlReader = 0
+        gridType  = GRID_NULL;
+    }
+
+    return xmlReader;
+}
+
+
+int vtk_celldim(int cellType)
+{
+    TRI_LOG_STR("vtk_celldim()");
+    TRI_LOG(cellType);
+
+    if ((cellType == VTK_TRIANGLE) ||
+        (cellType == VTK_QUADRATIC_TRIANGLE) ||
+        (cellType == VTK_PARAMETRIC_TRI_SURFACE) ||
+        (cellType == VTK_HIGHER_ORDER_TRIANGLE))
+    {
+        return 2;
+    }
+
+    if ((cellType == VTK_QUAD) ||
+        (cellType == VTK_QUADRATIC_QUAD) ||
+        (cellType == VTK_PARAMETRIC_QUAD_SURFACE) ||
+        (cellType == VTK_HIGHER_ORDER_QUAD))
+    {
+        return 2;
+    }
+
+    if ((cellType == VTK_TETRA) ||
+        (cellType == VTK_QUADRATIC_TETRA) ||
+        (cellType == VTK_PARAMETRIC_TETRA_REGION) ||
+        (cellType == VTK_HIGHER_ORDER_TETRAHEDRON))
+    {
+        return 3;
+    }
+
+    if ((cellType == VTK_VOXEL) ||
+        (cellType == VTK_HEXAHEDRON) ||
+        (cellType == VTK_QUADRATIC_HEXAHEDRON) ||
+        (cellType == VTK_PARAMETRIC_HEX_REGION) ||
+        (cellType == VTK_HIGHER_ORDER_HEXAHEDRON))
+    {
+        return 3;
+    }
+
+    return -1;
+}
+
+
+#endif

Added: cs/cigma/trunk/src/io_vtk.h
===================================================================
--- cs/cigma/trunk/src/io_vtk.h	                        (rev 0)
+++ cs/cigma/trunk/src/io_vtk.h	2008-12-10 02:16:36 UTC (rev 13634)
@@ -0,0 +1,313 @@
+#ifndef __CIGMA_IO_VTK_H__
+#define __CIGMA_IO_VTK_H__
+
+/* XXX: Move this to Definitions.h header? */
+
+typedef enum
+{
+    GRID_NULL=0,
+    GRID_VTK,
+    GRID_VTS,
+    GRID_VTR,
+    GRID_VTU,
+    GRID_PVTR,
+    GRID_PVTS,
+    GRID_PVTU
+} vtkGridType;
+
+
+#ifdef HAVE_VTK
+
+#include <sstream>
+#include <cassert>
+
+#include "tri_logger.hpp"
+#include "Exception.h"
+
+#include "vtkRectilinearGridReader.h"
+#include "vtkStructuredGridReader.h"
+#include "vtkUnstructuredGridReader.h"
+
+#include "vtkXMLRectilinearGridReader.h"
+#include "vtkXMLStructuredGridReader.h"
+#include "vtkXMLUnstructuredGridReader.h"
+
+#include "vtkXMLPRectilinearGridReader.h"
+#include "vtkXMLPStructuredGridReader.h"
+#include "vtkXMLPUnstructuredGridReader.h"
+
+#include "vtkDataSet.h"
+#include "vtkPointData.h"
+
+#include "vtkDataArray.h"
+#include "vtkDataArraySelection.h"
+
+#include "vtkIdList.h"
+#include "vtkCell.h"
+#include "vtkGenericCell.h"
+
+#include "vtkType.h"
+
+
+template <typename T>
+int vtk_datatype_from()
+{
+    throw cigma::Exception("vtk_datatype_from", "no mapping available for this VTK datatype");
+}
+
+std::string vtk_datatype_name(int datatype);
+
+vtkDataSetReader* vtk_open_legacy(const char *filename, vtkGridType& gridType);
+
+vtkXMLReader* vtk_open_xml(const char *filename, vtkGridType& gridType);
+
+int vtk_celldim(int cellType);
+
+
+template <typename T>
+int vtk_read_array(vtkDataSet* dataset, const char *loc, T** data, int *num, int *dim)
+{
+    TRI_LOG_STR("vtk_read_array()");
+    TRI_LOG(loc);
+
+    if (dataset == 0)
+    {
+        return -1;
+    }
+
+    int i,j;
+    int npts;
+    int rank;
+
+    T* array = 0;
+
+    vtkPointData *pointData = dataset->GetPointData();
+
+    if (pointData == 0)
+    {
+        throw cigma::Exception("vtk_read_array", "Could not read VTK Point Data from dataset", 1);
+    }
+
+    if (pointData->HasArray(loc) == 1)
+    {
+        vtkDataArray *dataArray = pointData->GetArray(loc);
+
+        if (dataArray == 0)
+        {
+            std::ostringstream stream;
+            stream << "failed to get array '" << loc << "' from VTK Point Data" << std::ends;
+            throw cigma::Exception("vtk_read_array", stream.str(), 2);
+        }
+
+        int datatype = dataArray->GetDataType();
+
+        TRI_LOG(datatype);
+
+        // verify we are loading a dataset of the correct type
+        if (datatype != vtk_datatype_from<T>())
+        {
+            std::ostringstream stream;
+            string name = vtk_datatype_name(datatype);
+            string expected  = vtk_datatype_name(vtk_datatype_from<T>());
+            stream << "Invalid vtk datatype (got "
+                   << name << " array, expected "
+                   << expected << " array)"
+                   << std::ends;
+            throw cigma::Exception("vtk_read_array", stream.str(), 3);
+        }
+
+        npts = dataArray->GetNumberOfTuples();
+        rank = dataArray->GetNumberOfComponents();
+
+        TRI_LOG(npts);
+        TRI_LOG(rank);
+
+        if (datatype == VTK_INT)
+        {
+            array = new T[npts * rank];
+            vtkIntArray* x = static_cast<vtkIntArray*>(dataArray);
+            for (i = 0; i < npts; i++)
+            {
+                int tuple[rank];
+                x->GetTupleValue(i, tuple);
+                for (j = 0; j < rank; j++)
+                {
+                    array[i*rank + j] = tuple[j];
+                }
+            }
+        }
+        else if (datatype == VTK_LONG)
+        {
+            array = new T[npts * rank];
+            vtkLongArray* x = static_cast<vtkLongArray*>(dataArray);
+            for (i = 0; i < npts; i++)
+            {
+                long tuple[rank];
+                x->GetTupleValue(i, tuple);
+                for (j = 0; j < rank; j++)
+                {
+                    array[i*rank + j] = tuple[j];
+                }
+            }
+        }
+        else if (datatype == VTK_FLOAT)
+        {
+            array = new T[npts * rank];
+            vtkFloatArray* x = static_cast<vtkFloatArray*>(dataArray);
+            for (i = 0; i < npts; i++)
+            {
+                float tuple[rank];
+                x->GetTupleValue(i, tuple);
+                for (j = 0; j < rank; j++)
+                {
+                    array[i*rank + j] = tuple[j];
+                }
+            }
+        }
+        else if (datatype == VTK_DOUBLE)
+        {
+            array = new T[npts * rank];
+            vtkDoubleArray* x = static_cast<vtkDoubleArray*>(dataArray);
+            for (i = 0; i < npts; i++)
+            {
+                double tuple[rank];
+                x->GetTupleValue(i, tuple);
+                for (j = 0; j < rank; j++)
+                {
+                    array[i*rank + j] = tuple[j];
+                }
+            }
+        }
+        else
+        {
+            std::ostringstream stream;
+            std::string name = vtk_datatype_name(datatype);
+            stream << "Need handler for " << name << " datatype" << std::ends;
+            throw cigma::Exception("vtk_read_array", stream.str(), 4);
+        }
+    }
+    else
+    {
+        std::ostringstream stream;
+        stream << "array '" << loc << "' does not exist" << std::ends;
+        throw cigma::Exception("vtk_read_array", stream.str(), 5);
+    }
+
+    *data = array;
+    *num  = npts;
+    *dim  = rank;
+
+    return 0;
+}
+
+/**
+ * Read coordinates from given vtkDataSet
+ * @param CoordType A C++ type for components (float, double)
+ *
+ */
+template <typename CoordType>
+int vtk_read_coordinates(vtkDataSet* dataset, const char *loc, CoordType** coords, int *nno, int *nsd)
+{
+    TRI_LOG_STR("vtk_read_coordinates()");
+    TRI_LOG(loc);
+
+    if (dataset == 0)
+    {
+        return -1;
+    }
+
+    int i,j;
+    int npts;
+    int ndims;
+
+    int cellType = dataset->GetCellType(0); // XXX: assumes uniform cell types
+
+    npts = dataset->GetNumberOfPoints();
+    ndims = vtk_celldim(cellType);
+
+    TRI_LOG(npts);
+    TRI_LOG(ndims);
+
+    if ((ndims < 0) || (ndims > 3))
+    {
+        std::ostringstream stream;
+        stream << "Invalid cell dimension (got " << ndims << ")" << std::ends;
+        throw cigma::Exception("vtk_read_coords", stream.str(), 1);
+    }
+
+    array = new CoordType[npts * ndims];
+
+    for (i = 0; i < npts; i++)
+    {
+        double point[3];
+        
+        dataset->GetPoint(i, point);
+
+        for (j = 0; j < ndims; j++)
+        {
+            array[i*ndims + j] = point[j];
+        }
+    }
+
+    *coords = array;
+    *nno    = npts;
+    *nsd    = ndims;
+
+    return 0;
+}
+
+
+/**
+ * Read connectivity information from given vtkDataSet
+ * @param IdType A C++ type for indices (int, long, vtkIdType)
+ */
+template <typename IdType>
+int vtk_read_connectivity(vtkDataSet* dataset, const char *loc, IdType** connect, int *nel, int *ndofs)
+{
+    TRI_LOG_STR("vtk_read_connectivity()");
+    TRI_LOG(loc);
+
+    if (dataset == 0)
+    {
+        return -1;
+    }
+
+    int i,j;
+    int ncells;
+    int nverts;
+
+    // XXX: write function to check that the entire array of cell types is uniform
+
+    vtkCell *firstCell = dataset->GetCell(0); // XXX: assumes uniform cell types
+    ncells = dataset->GetNumberOfCells();
+    nverts = firstCell->GetNumberOfPoints();
+
+    TRI_LOG(ncells);
+    TRI_LOG(nverts);
+
+    array = new IdType[ncells * nverts];
+
+    vtkGenericCell *cell = vtkGenericCell::New();
+
+    for (i = 0; i < ncells; i++)
+    {
+        dataset->GetCell(i, cell);
+
+        for (j = 0; j < nverts; j++)
+        {
+            array[i * nverts + j] = cell->GetPointIds()->GetId(j);
+        }
+    }
+
+    cell->Delete();
+
+    *connect = array;
+    *nel     = ncells;
+    *ndofs   = nverts;
+
+    return 0;
+}
+
+
+#endif /* HAVE_VTK */
+#endif /* __CIGMA_IO_VTK_H__ */



More information about the CIG-COMMITS mailing list