Read NetGen neutral mesh files via a python algorithm plugin

If you have a mesh in NetGen’s neutral file format (a simple ASCII file), this python algorithm:

"""Read Netgen neutral files."""

from __future__ import print_function
from paraview.util.vtkAlgorithm import *

@smproxy.reader(extensions="netgen", file_description="Netgen neutral mesh", label="Netgen mesh reader", support_reload=True)
class NetgenReader(VTKPythonAlgorithmBase):
    def __init__(self):
        VTKPythonAlgorithmBase.__init__(self, nInputPorts=0, nOutputPorts=1, outputType='vtkMultiBlockDataSet')
        self._filename = None
        self._ndata = None
        self._timesteps = None

    @smproperty.stringvector(name="FileName")
    @smdomain.filelist()
    @smhint.filechooser(extensions="netgen", file_description="Netgen neutral mesh")
    def SetFileName(self, fname):
        """Specify filename for the file to write."""
        if self._filename != fname:
            self._filename = fname
            self.Modified()

    def RequestData(self, request, inInfoVec, outInfoVec):
        from vtkmodules.vtkCommonCore import vtkPoints
        from vtkmodules.vtkCommonDataModel import \
                vtkPolyData, vtkUnstructuredGrid, vtkMultiBlockDataSet, vtkCellArray, \
                VTK_TETRA, VTK_TRIANGLE
        mbds = vtkMultiBlockDataSet.GetData(outInfoVec, 0)
        try:
            mfile = open(self._filename, 'r')
        except:
            print('Could not open file "%s"' % self._filename)
            return 0
        numPoints = int(next(mfile))
        pts = vtkPoints()
        pts.SetNumberOfPoints(numPoints)
        for pp in range(numPoints):
            pts.SetPoint(pp, [float(x) for x in next(mfile).split()])
        mbds.SetNumberOfBlocks(2) # Output is divided into surfaces and volumes
        vblocks = []
        sblocks = []
        mesh = None
        lastRegion = None
        numTetra = int(next(mfile))
        for tt in range(numTetra):
            conn = [int(x) - 1 for x in next(mfile).split()]
            if conn[0] != lastRegion:
                if conn[0] < len(vblocks):
                    mesh = vblocks[conn[0]]
                else:
                    mesh = vtkUnstructuredGrid()
                    mesh.SetPoints(pts)
                    vblocks.append(mesh)
                lastRegion = conn[0]
            mesh.InsertNextCell(VTK_TETRA, 4, conn[1:])
        numTri = int(next(mfile))
        lastSurface = None
        for tt in range(numTri):
            conn = [int(x) - 1 for x in next(mfile).split()]
            if conn[0] != lastSurface:
                if conn[0] < len(sblocks):
                    mesh = sblocks[conn[0]]
                    cell = mesh.GetPolys()
                else:
                    mesh = vtkPolyData()
                    mesh.SetPoints(pts)
                    cell = vtkCellArray()
                    mesh.SetPolys(cell)
                    sblocks.append(mesh)
                lastSurface = conn[0]
            cell.InsertNextCell(3, conn[1:])
        vb = vtkMultiBlockDataSet()
        sb = vtkMultiBlockDataSet()
        mbds.SetBlock(0, vb)
        mbds.SetBlock(1, sb)
        vb.SetNumberOfBlocks(len(vblocks))
        sb.SetNumberOfBlocks(len(sblocks))
        for bb in range(len(vblocks)):
            vb.SetBlock(bb, vblocks[bb])
        for bb in range(len(sblocks)):
            sb.SetBlock(bb, sblocks[bb])
        mfile.close()
        return 1

can read it into ParaView. Just save the above into a python file and use ParaView’s Tools → ManagePlugins… menu to open the plugin manager. Click Load New… and choose the python file. Note that once you’ve loaded it, you might want to expand the plugin listing and click “Autoload” so the plugin is always loaded.

An example mesh for you to try is here: two-cubes.netgen (4.3 KB)

For reference, you can download the python above by clicking here: netgenreader.py (3.2 KB)

1 Like