Hi Ken,

Sorry for the slow reply.  What I have is a reader for poly files
(vtkPolyReader*) and a GMS mesh reader which I believe has the 3dm file
extension.  Hope this helps.

Andy

On Mon, May 3, 2010 at 4:29 PM, <[email protected]> wrote:

> Hi Andy,
>
> Thanks for your reply. It seems pretty similar. I can merge the outputs
> (element and node files) from Tetgen and then give a try to the plug-in you
> developed. Let me know if you are interested for sharing.
>
> Below is my guess on the mesh file format. Is it right?
> E4T(Element type)     1(Element Number)  4913  5569  4914  5530 (4 Nodes)
>     2(Material type)
>
> By the way, is it possible to read Abaqus mesh files into Paraview, or
> export mesh files in Paraview to a format which Abaqus could recognize?
>
> Thanks in advance,
>
> Ken
>
>
>
> On Fri, Apr 30, 2010 at 6:31 PM, Andy Bauer <[email protected]>wrote:
>
>> Hi Ken,
>>
>> I'm not familiar with the formats of the files you sent us.  I'm not that
>> familiar with tetgen either so it's possible that we may be talking about
>> the same software or we may not.  In any case, the tetgen output grid file
>> that I have looks like the following at the top:
>> MESH3D
>> E4T     1  4913  5569  4914  5530     2
>> E4T     2  4913  4953  4914  5569     2
>> E4T     3  4913  4952  5569  5568     2
>> E4T     4  4913  4952  4953  5569     2
>> E4T     5  4913  4912  5568  5528     2
>>
>> The nodes are listed second and look like:
>> ND     1 1672.1247729534 1357.9324205486 -14.27143712838
>> ND     2 1580.6340102853 1340.230370113 -3.885760029157
>> ND     3 1580.6340102853 1340.230370113 -14.12243425846
>>
>> These are the files that we are able to read.  Does this look like it's
>> from the same software?
>>
>> Andy
>>
>>
>>
>> On Fri, Apr 30, 2010 at 2:28 PM, <[email protected]> wrote:
>>
>>> Hi Andy,
>>>
>>> Thanks for the reply. See the attachment for an example mesh.
>>>
>>> By the way, is it possible to read Abaqus mesh files to Paraview, or
>>> export mesh files in Paraview to a format which Abaqus could recognize?
>>>
>>> Have a good one,
>>>
>>> Ken
>>>
>>>
>>>
>>>
>>>
>>> On Fri, Apr 30, 2010 at 8:54 AM, Andy Bauer <[email protected]>wrote:
>>>
>>>> Hi Ken,
>>>>
>>>> I think there may be a tetgen reader that we've developed for a
>>>> different project.  I may be able to move it to ParaView/VTK but will have
>>>> to check with the sponsor.  Could you send a small sample file so that I 
>>>> can
>>>> make sure that it's the same file type?
>>>>
>>>> Andy
>>>>
>>>> On Fri, Apr 30, 2010 at 1:39 AM, <[email protected]> wrote:
>>>>
>>>>> Hi all,
>>>>>
>>>>> Dose anyone have any experience in reading meshes (*.node *.ele *.face)
>>>>> generated with Tetgen in Paraview?
>>>>>
>>>>> Thanks,
>>>>>
>>>>> Ken
>>>>>
>>>>>
>>>>> _______________________________________________
>>>>> Powered by www.kitware.com
>>>>>
>>>>> Visit other Kitware open-source projects at
>>>>> http://www.kitware.com/opensource/opensource.html
>>>>>
>>>>> Please keep messages on-topic and check the ParaView Wiki at:
>>>>> http://paraview.org/Wiki/ParaView
>>>>>
>>>>> Follow this link to subscribe/unsubscribe:
>>>>> http://www.paraview.org/mailman/listinfo/paraview
>>>>>
>>>>>
>>>>
>>>
>>
>
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkGMSMeshReader.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 "vtkGMSMeshReader.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkDoubleArray.h"
#include "vtkErrorCode.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkIntArray.h"
#include "vtkObjectFactory.h"
#include "vtkPoints.h"
#include "vtkUnstructuredGrid.h"
#include "vtkMultiBlockWrapper.h"

#include <vtkstd/string>
#include <sys/stat.h>

vtkCxxRevisionMacro(vtkGMSMeshReader, "$Revision: 470 $");
vtkStandardNewMacro(vtkGMSMeshReader);

struct vtkGMSMeshReaderInternals
{
  ifstream* Stream;

  vtkGMSMeshReaderInternals() : Stream(0) {}
  ~vtkGMSMeshReaderInternals()
    {
      this->DeleteStream();
    }
  void DeleteStream()
    {
      delete this->Stream;
      this->Stream = 0;
    }
};

//----------------------------------------------------------------------------
vtkGMSMeshReader::vtkGMSMeshReader()
{
  this->FileName  = NULL;
  this->SetNumberOfInputPorts(0);
  this->Internals = new vtkGMSMeshReaderInternals;
}

//----------------------------------------------------------------------------
vtkGMSMeshReader::~vtkGMSMeshReader()
{
  delete[] this->FileName;
  delete this->Internals;
}

//----------------------------------------------------------------------------
int vtkGMSMeshReader::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *outputVector)
{
  if (!this->FileName || (strlen(this->FileName) == 0))
    {
    vtkErrorMacro("FileName has to be specified!");
    return 0;
    }

  vtkInformation *outInfo = outputVector->GetInformationObject(0);

  vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
    outInfo->Get(vtkDataObject::DATA_OBJECT()));

  struct stat fs;
  if (stat(this->FileName, &fs) != 0) 
    {
    vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
    this->SetErrorCode( vtkErrorCode::CannotOpenFileError );
    return 0;
    }

  this->Internals->Stream = new ifstream(this->FileName, ios::in);
  if (this->Internals->Stream->fail())
    {
    vtkErrorMacro(<< "Unable to open file: "<< this->FileName);
    this->SetErrorCode( vtkErrorCode::CannotOpenFileError );
    this->Internals->DeleteStream();
    return 0;
    }

  // We don't know the size of the data so make up something. We still
  // have to allocate.
  output->Allocate(200, 100);

  vtkstd::string header;
  *this->Internals->Stream >> header;
  // This reader supports both MESH2D and MESH3D
  if (header != "MESH2D" && header != "MESH3D")
    {
    vtkErrorMacro("Failed reader MESH2D card in the header.");
    this->SetErrorCode( vtkErrorCode::FileFormatError );
    this->Internals->DeleteStream();
    return 0;
    }

  vtkPoints* pts = vtkPoints::New();
  pts->SetDataTypeToDouble();
  output->SetPoints(pts);
  pts->Delete();
  vtkDoubleArray* dpts = vtkDoubleArray::SafeDownCast(pts->GetData());

  vtkIntArray* regionArray = vtkIntArray::New();
  regionArray->SetName(vtkMultiBlockWrapper::GetShellTagName());
  output->GetCellData()->AddArray(regionArray);
  regionArray->Delete();

  while(!this->Internals->Stream->eof())
    {
    vtkstd::string cardName;
    *this->Internals->Stream >> cardName;
    if (cardName == "E3T")
      {
      this->ReadCell(VTK_TRIANGLE, 3, output, regionArray);
      }
    else if (cardName == "E6T")
      {
      this->ReadCell(VTK_QUADRATIC_TRIANGLE, 6, output, regionArray);
      }
    else if (cardName == "E4Q")
      {
      this->ReadCell(VTK_QUAD, 4, output, regionArray);
      }
    else if (cardName == "E8Q")
      {
      this->ReadCell(VTK_QUADRATIC_QUAD, 8, output, regionArray);
      }
    else if (cardName == "E4T")
      {
      this->ReadCell(VTK_TETRA, 4, output, regionArray);
      }
    else if (cardName == "E5P")
      {
      this->ReadCell(VTK_PYRAMID, 6, output, regionArray);
      }
    else if (cardName == "E6W")
      {
      this->ReadCell(VTK_WEDGE, 6, output, regionArray);
      }
    else if (cardName == "E8H")
      {
      this->ReadCell(VTK_HEXAHEDRON, 8, output, regionArray);
      }
    else if (cardName == "ND")
      {
      this->ReadNode(dpts);
      }
    }
  this->Internals->DeleteStream();
  return 1;
}

//----------------------------------------------------------------------------
void vtkGMSMeshReader::ReadCell(int cellType,
                                  int numPts, 
                                  vtkUnstructuredGrid* output,
                                  vtkIntArray* regionArray)
{
  int i;
  vtkIdType id;
  vtkIdType ptIds[8];
  int material;
  *this->Internals->Stream >> id;
  for (i=0; i<numPts; i++)
    {
    *this->Internals->Stream >> ptIds[i];
    }
  *this->Internals->Stream >> material;
  // Our indices start at 0, file format's at 1. Subtract 1 from indices.
  for (i=0; i<numPts; i++) 
    {
    ptIds[i]--;
    }
  vtkIdType pid = -1;
  if (cellType == VTK_QUADRATIC_TRIANGLE)
    {
    // The point ordering of VTK and the file format are different.
    // Re-order to match VTK's
    vtkIdType vtkIds[6];
    unsigned int indices[6] = {0, 3, 1, 4, 2, 5};
    for (i=0; i<6; i++)
      {
      vtkIds[indices[i]] = ptIds[i];
      }
    pid = output->InsertNextCell(cellType, numPts, vtkIds);
    }
  else if (cellType == VTK_QUADRATIC_QUAD)
    {
    // The point ordering of VTK and the file format are different.
    // Re-order to match VTK's
    vtkIdType vtkIds[8];
    unsigned int indices[8] = {0, 4, 1, 5, 2, 6, 3, 7};
    for (i=0; i<8; i++)
      {
      vtkIds[indices[i]] = ptIds[i];
      }
    pid = output->InsertNextCell(cellType, numPts, vtkIds);
    }
  else
    {
    pid = output->InsertNextCell(cellType, numPts, ptIds);
    }
  regionArray->InsertValue(pid, material);
}

//----------------------------------------------------------------------------
void vtkGMSMeshReader::ReadNode(vtkDoubleArray* dpts)
{
  vtkIdType id;
  double pts[3];
  *this->Internals->Stream >> id >> pts[0] >> pts[1] >> pts[2];
  dpts->InsertTuple(id-1, pts);
}

//----------------------------------------------------------------------------
void vtkGMSMeshReader::PrintSelf(ostream& os, vtkIndent indent)
{ 
  this->Superclass::PrintSelf(os,indent);
  os << indent << "File Name: " 
     << (this->FileName ? this->FileName : "(none)") << endl;
}

//----------------------------------------------------------------------------
int vtkGMSMeshReader::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  if (!this->FileName)
    {
    vtkErrorMacro("FileName has to be specified!");
    return 0;
    }

  return 1;
}

/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkGMSMeshReader.h,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.

=========================================================================*/
// .NAME vtkGMSMeshReader - Reader for GMS mesh2D and mesh3D files
// .SECTION Description
// vtkGMSMeshReader reads 2D and 3D GMS meshes written in ASCII. It
// is assumed that point indices start from 1 and that there are no
// gaps in point data indices.
// Supported elements are: E3T E6T E4Q E8Q E4T E5P E6W E8H

#ifndef __vtkGMSMeshReader_h
#define __vtkGMSMeshReader_h

#include "vtkUnstructuredGridAlgorithm.h"

//BTX
struct vtkGMSMeshReaderInternals;
//ETX

class vtkDoubleArray;
class vtkIntArray;
class vtkUnstructuredGrid;

class VTK_EXPORT vtkGMSMeshReader : public vtkUnstructuredGridAlgorithm
{
public:
  static vtkGMSMeshReader *New();
  vtkTypeRevisionMacro(vtkGMSMeshReader,vtkUnstructuredGridAlgorithm);
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Name of the file to be read.
  vtkSetStringMacro(FileName);
  vtkGetStringMacro(FileName);

protected:
  vtkGMSMeshReader();
  ~vtkGMSMeshReader();

  int RequestInformation(vtkInformation *, 
                         vtkInformationVector **, 
                         vtkInformationVector *);
  int RequestData(vtkInformation *, 
                  vtkInformationVector **, 
                  vtkInformationVector *);

  void ReadCell(int cellType, int npts, vtkUnstructuredGrid*, vtkIntArray*);
  void ReadNode(vtkDoubleArray*);

  char * FileName;

private:
  vtkGMSMeshReader(const vtkGMSMeshReader&);  // Not implemented.
  void operator=(const vtkGMSMeshReader&);  // Not implemented.

  vtkGMSMeshReaderInternals* Internals;
};
#endif
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkPolyReader.h,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.

=========================================================================*/
// .NAME vtkPolyReader - Reader for *.poly files
// .SECTION Description
// Reader for *.poly files.  The format is simple, conatining only points and
// then indices for each facet, which is made up of polygons.  Currently
// the reader doesn't handle holes in facets (ignores them), but does add
// field data for each facet (the facet index) as well as the boundary marker
// value (if present).

#ifndef __PolyReader_h
#define __PolyReader_h

#include "vtkPolyDataAlgorithm.h"

class VTK_EXPORT vtkPolyReader : public vtkPolyDataAlgorithm
{
public:
  static vtkPolyReader *New();
  vtkTypeRevisionMacro(vtkPolyReader,vtkPolyDataAlgorithm);
  void PrintSelf(ostream& os, vtkIndent indent);

  // Description:
  // Name of the file to be read.
  vtkSetStringMacro(FileName);
  vtkGetStringMacro(FileName);

protected:
  vtkPolyReader();
  ~vtkPolyReader();

  int RequestInformation(vtkInformation *, 
                         vtkInformationVector **, 
                         vtkInformationVector *);
  int RequestData(vtkInformation *, vtkInformationVector **, vtkInformationVector *);
  char *FileName;

  //BTX
  // Description:
  // Get next line of data (and put in lineStream); skips over comments or blank lines
  int GetNextLineOfData(ifstream &fin, vtkstd::stringstream &lineStream);
  //ETX

private:
  vtkPolyReader(const vtkPolyReader&);  // Not implemented.
  void operator=(const vtkPolyReader&);  // Not implemented.
};

#endif
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    $RCSfile: vtkGMSSolidReader.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 "vtkPolyReader.h"

#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkInformation.h"
#include "vtkInformationVector.h"
#include "vtkMultiBlockWrapper.h"
#include "vtkObjectFactory.h"
#include "vtkPolyData.h"
#include "vtkSmartPointer.h"
#include <vtkstd/vector>
#include <sys/types.h>
#include <sys/stat.h>

#include <vtkstd/string>
#include <vtksys/ios/sstream>


vtkCxxRevisionMacro(vtkPolyReader, "$Revision: 745 $");
vtkStandardNewMacro(vtkPolyReader);

//-----------------------------------------------------------------------------
vtkPolyReader::vtkPolyReader()
{
  this->FileName = NULL;
  this->SetNumberOfInputPorts(0);
}

//-----------------------------------------------------------------------------
vtkPolyReader::~vtkPolyReader()
{
  this->SetFileName(0);
}

//-----------------------------------------------------------------------------
int vtkPolyReader::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()));

  ifstream fin(this->FileName);
  if(!fin)
    {
    vtkErrorMacro(<< "File " << this->FileName << " not found");
    return 0;
    }

  int idx, numPts, dimension, numberOfAttributes, hasBoundaryMarkers;
  double pt[3];

  this->UpdateProgress(0.0);

  numPts = -1;

  // get the number of points

  // numPts could actually be 0, indicating points are listed in a separate
  // .node file
  vtkstd::stringstream lineStream;
  this->GetNextLineOfData(fin, lineStream);
  lineStream >> numPts >> dimension >> numberOfAttributes >> hasBoundaryMarkers;

  // if numPts == 0 then we need to read them from a .node file

  vtkPoints *newPts = vtkPoints::New();
  newPts->SetDataTypeToDouble();
  newPts->Allocate(numPts);

  // now actually read the points
  int ptIndex;
  for (idx = 0;  idx < numPts; idx++)
    {
    this->GetNextLineOfData(fin, lineStream);
    lineStream >> ptIndex >> pt[0] >> pt[1] >> pt[2];
    if ((idx%1000)==0)
      {
      this->UpdateProgress( 0.5 * idx / numPts );
      }
    newPts->InsertNextPoint(pt);

    // read any attributes (just throwing away right now)
    double attribute;
    for (int i = 0; i < numberOfAttributes; i++)
      {
      lineStream >> attribute;
      }

    // get boundary marker
    int boundaryMarker;
    if (hasBoundaryMarkers)
      {
      lineStream >> boundaryMarker;
      }
    }

  vtkIdType numFacets = 0, hasFacetBoundaryMarkers;

  // number of facets
  this->GetNextLineOfData(fin, lineStream);
  lineStream >> numFacets >> hasFacetBoundaryMarkers;

  vtkCellArray *newPolys = vtkCellArray::New();
  // assume triangles (and one poly per facet)
  newPolys->Allocate(4 * numFacets);

  vtkSmartPointer<vtkIntArray> faceIDs = vtkSmartPointer<vtkIntArray>::New();
  faceIDs->SetName( vtkMultiBlockWrapper::GetModelFaceTagName() );
  faceIDs->Allocate( numFacets );
  output->GetCellData()->AddArray( faceIDs );

  vtkSmartPointer<vtkIntArray> boundaryMarkerIDs;
  if (hasFacetBoundaryMarkers)
    {
    boundaryMarkerIDs = vtkSmartPointer<vtkIntArray>::New();
    boundaryMarkerIDs->SetName( "BoundaryMarkers" );
    boundaryMarkerIDs->Allocate( numFacets );
    output->GetCellData()->AddArray( boundaryMarkerIDs );
    }

  int holeIndex, ptsInPoly, indicesSize = 5; 
  int numberOfPolygons, numberOfHoles, boundaryMarker;
  vtkIdType* indices = new vtkIdType[5];
  for (int faceIdx = 0;  faceIdx < numFacets; faceIdx++)
    {
    numberOfHoles = boundaryMarker = 0;
    this->GetNextLineOfData(fin, lineStream);
    lineStream >> numberOfPolygons >> numberOfHoles >> boundaryMarker;

    // get the polygons making up this facet
    for (int i = 0; i < numberOfPolygons; i++)
      {
      this->GetNextLineOfData(fin, lineStream);
      lineStream >> ptsInPoly;
      // make sure we have enough space to store the indices
      if (ptsInPoly > indicesSize)
        {
        delete [] indices;
        indicesSize = ptsInPoly;
        indices = new vtkIdType [indicesSize];
        }

      for (int j = 0; j < ptsInPoly; j++)
        {
        lineStream >> indices[j];
        indices[j]--; // indices are 1-based (need to convert to 0-based)
        }
      newPolys->InsertNextCell(ptsInPoly, indices);
      faceIDs->InsertNextValue(faceIdx);
      if (hasFacetBoundaryMarkers)
        {
        boundaryMarkerIDs->InsertNextValue( boundaryMarker );
        }
      }
    
    // and any holes in the facet (throw away for now)
    for (int i = 0; i < numberOfHoles; i++)
      {
      this->GetNextLineOfData(fin, lineStream);
      lineStream >> holeIndex >> pt[0] >> pt[1] >> pt[2];
      }

    this->UpdateProgress( 0.5 + 0.5 * faceIdx / numFacets );
    }
  delete [] indices;

  // now get volume holes
  int numberOfVolumeHoles;
  this->GetNextLineOfData(fin, lineStream);
  lineStream >> numberOfVolumeHoles;
  for (int i = 0; i < numberOfVolumeHoles; i++)
    {
    this->GetNextLineOfData(fin, lineStream);
    lineStream >> holeIndex >> pt[0] >> pt[1] >> pt[2];
    }

  // and finally the region attribute list (optional)
  if (this->GetNextLineOfData(fin, lineStream) == 1)
    {
    int numberOfRegions;
    lineStream >> numberOfRegions;
    // no as sure about the format here... will get back to
    }

  fin.close();
  this->UpdateProgress( 1.0 );

  output->SetPoints(newPts);
  newPts->Delete();

  output->SetPolys(newPolys);
  newPolys->Delete();

  return 1;
}

//-----------------------------------------------------------------------------
int vtkPolyReader::GetNextLineOfData(ifstream &fin, 
                                         vtkstd::stringstream &lineStream)
{
  // clear the string for the line
  lineStream.str("");
  lineStream.clear();
  char buffer[1024]; // a pretty long line!
  vtkstd::string testString;
  while(1)
    {
    fin.getline(buffer, 1024); 
    if (fin.eof())
      {
      return 0;
      }
    
    testString = buffer;
    // see if it is a comment or blank line
    if (testString == "" || testString.find("#") == 0)
      {
      continue;
      }

    // set the output stream
    lineStream << testString;
    return 1;
    }
}

//-----------------------------------------------------------------------------
void vtkPolyReader::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os,indent);

  os << indent << "File Name: " 
     << (this->FileName ? this->FileName : "(none)") << "\n";
}


//----------------------------------------------------------------------------
int vtkPolyReader::RequestInformation(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **vtkNotUsed(inputVector),
  vtkInformationVector *vtkNotUsed(outputVector))
{
  if (!this->FileName)
    {
    vtkErrorMacro("FileName has to be specified!");
    return 0;
    }

  return 1;
}

_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at 
http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the ParaView Wiki at: 
http://paraview.org/Wiki/ParaView

Follow this link to subscribe/unsubscribe:
http://www.paraview.org/mailman/listinfo/paraview

Reply via email to